Snabb och precis loop i C# Hjälp!

Elektronik- och mekanikrelaterad mjukvara/litteratur. (T.ex schema-CAD, simulering, böcker, manualer mm. OS-problem hör inte hit!)
Användarvisningsbild
Cenorpa
Inlägg: 737
Blev medlem: 11 juli 2005, 20:58:03
Ort: Stockholm | Borlänge
Kontakt:

Snabb och precis loop i C# Hjälp!

Inlägg av Cenorpa »

Hej. Sitter och håller på med ett ganska stort projekt och skulle behöva lite vägledning. Vet att det finns många duktiga programmerare här.

Det jag vill göra är en loop i C# som ropar på en USB-metod uppemot 35000 ggr / sekund för att skicka data ut över ett interface. Hur skapar jag denna loop är altså den stora frågan.

Loopen skall köras i bakgrunden av programmet och kontinuerligt skicka data vilket gör att det borde vara enklast att låta en egen tråd sköta om den loopen. Men hur skapar jag loopen så att den ropar på en metod med ett bestämt intervall (som i mitt fall är max 35000ggr / sekund)?
thepirateboy
EF Sponsor
Inlägg: 2109
Blev medlem: 27 augusti 2005, 20:57:58
Ort: Borlänge

Inlägg av thepirateboy »

Har du kollat på de timers som finns i C#? Nackdelen med de vanliga timrarna är att de är inte är så noggranna och minsta tid är 1 ms. Här verkar finnas nåt liknande men med högre upplösning som kanske går att använda:

http://www.codeproject.com/KB/cs/highpe ... cshar.aspx

35000 ggr/sekund låter för övrigt ganska mycket...
sodjan
EF Sponsor
Inlägg: 43249
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

Alltså ett anrop och en USB överföring var 28'de mikrosekund ?
Var är "ett interface" som det ska skickas över ? USB interfacet?
Vad har du gjort för analyser för att komma fram till att
det överhuvudtaget är något som fungerar ? D.v.s att hela
miljön med C#, .NET, Windows o.s.v fixar att köra 35000
överföringer per sekund ?

Om du kan beskriva bättre vad det hela ska göra så
kanske det är att förstå bättre.
Användarvisningsbild
Cenorpa
Inlägg: 737
Blev medlem: 11 juli 2005, 20:58:03
Ort: Stockholm | Borlänge
Kontakt:

Inlägg av Cenorpa »

Vill inte avslöja allt för mycket än. Men det jag använder är ett FT245R chip från ftdi och vill skicka "lite" data till. Men jag kan nog kanske göra hårdvaran lite smartare och skicka större datapaket åt gången istället så blir det genast mycket enklare. Vet inte riktigt hur den slutgiltiga designen kommer att se ut men efter lite beräkningar nu så kommer jag ner till 1500ggr / sekund vilket inte borde vara något problem alls.

Men min fråga finns fortfarande kvar fast med lite lägre krav. Hur gör jag nu en loop som skickar ut data 1500ggr / sekund. alltså uppdateras med 1,5KHz.
Det är bara själva loopen jag behöver ha hjälp med. Vanliga timers är för lågupplösta och inte alls speciellt exakta. Jag vill alltså placera den här loopen innuti en separat tråd som körs i bakgrunden och göra något liknande som Thread.sleep inuti själva loopen fast i ett mindre intervall än 1ms som är den lägsta upplösningen där.

Det ska ju helst vara så att man spar på lite processorkraft också så att inte loopen ligger och kör med full fart hela tiden utan att det finns en viss begränsning där precis som sleep fungerar.
sodjan
EF Sponsor
Inlägg: 43249
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

Ska den där "loopen" vara self-timed, eller är det något anrop till
den som triggar en överföring? Hur vet den när den ska skicka ?
Var kommer datat från som den ska skicka ?

Vad ska det köra på? Windows ? Hur långa avbrott kan du acceptera
i dina 1500 tusen paket per sekund ? Windows i sig garanterar inte
att det rullar på jämt och stadigt.

Rent spontant så är jag tveksam om du kan få 1500 paket/sekund
över USB från C#. Frågan är om det inte behövs en en "driver" för
att fixa det.
Användarvisningsbild
Cenorpa
Inlägg: 737
Blev medlem: 11 juli 2005, 20:58:03
Ort: Stockholm | Borlänge
Kontakt:

Inlägg av Cenorpa »

Ja loopen skall köra av sig själv och på en windows maskin. Data kommer från en ByteArray men det bearbetas i USBoutput.

Såhär hade jag tänkt:

Kod: Markera allt

        private void Run()
        {
            while (RunThread== true)
            {
                Thread.Sleep(660µs);
                USBOutput();
            }
        }
Fast Thread.sleep kan ju inte definieras för µs.
Medans RunThread = sant så körs loopen.
Hela funktionen Run() körs i en egen tråd i bakgrunden och när RunThread sätts till falskt så stannar tråden.

Fast jag börjar mer och mer fundera på en tvåvägskommunikation istället där hårdvaran berättar för datorn när det är dags att skicka nästa datapaket ifall det är möjligt. Måste kolla lite mer på det.
Användarvisningsbild
speakman
Inlägg: 4838
Blev medlem: 18 augusti 2004, 23:03:32
Ort: Ånge

Inlägg av speakman »

Största problemet är väl att det sällan ö.h.t. existerar något som kan räkna tid i lägre än 1KHz i de flesta system. Det är väl heller inte ofta något behöver taktas snabbare, då brukar det röra sig om att knuffa över större buffertar i stöten (tänk ljudkort över USB etc).

En lika stor fråga är väl om FTDI-kretsen verkligen klarar 35KHz? 1,5KHz låter mer troligt, men jag tycker det ändå låter lite designmiss över det hela.

Om inte allt vore så hemligt kanske vi kunde bidra med lösning på designproblemet istället. Är USB egentligen lägligt t.ex.?

En "lösning" kan vara att göra en egen hårdvara som kan skicka interrupt i den frekvens du behöver, och sedan skriva en driver som skickar vidare dessa in i ditt program, samt hoppas att det hänger med.
Nerre
Inlägg: 27205
Blev medlem: 19 maj 2008, 07:51:04
Ort: Upplands väsby

Inlägg av Nerre »

Är USB konstruerat för realtidsöverföring?

Annars riskerar man ju att datat ändå buffras i nån krets och inte alls kommer i det tempo man tänkt sig.

Windows är ju också ett multitaskande operativ så det finns säkerligen en massa trådar som körs med högre prioritet och kommer att kunna sabba det hela.
Användarvisningsbild
Cenorpa
Inlägg: 737
Blev medlem: 11 juli 2005, 20:58:03
Ort: Stockholm | Borlänge
Kontakt:

Inlägg av Cenorpa »

FTDI kretsen klarar upp till 1Mbyte / sekund överföringshastighet. Den har en inbyggd buffert på 256byte.
Om vi säger att vi fyller upp bufferten vid varje överföring så blir det ca 3900 överföringar / sekund vilket gör att mitt värde på 1500 / sekund borde vara inom rimliga gränser.

Jag vill kunna överföra maximalt uppemot 0,1545Mega byte / sekund vilket är endast ca 15% av den maximala hastigheten som kretsen klarar vilket inte alls borde vara något problem.
Men jag börjar mer och mer fundera på att det är hårdvaran som får tala om när den har bearbetat klart informationen och den är redo att ta emot ny.

Det är ingen realtidsöverföring jag är ute efter nu för det har jag insett att det inte kommer att fungera.

Men det måste väl finnas någon lösning ändå som jag syftar på med loopen även om det inte är det som kommer att användas i slutändan. Jag vet att man kan kolla antalet ticks som systemklockan har gjort men då måste ju loopen snurra på hela tiden och kolla denna konstant vilket suger processorkraft.
Användarvisningsbild
speakman
Inlägg: 4838
Blev medlem: 18 augusti 2004, 23:03:32
Ort: Ånge

Inlägg av speakman »

Om man kollar specen på USB så ser man också att det alltid är hosten som initierar en överföring och aldrig devicen. Den pollar alltså. Och före USB2.0 verkar denna poll varit cyklad på 1ms, men 2.0 erbjuder ytterligare 125 µs "microframes". Dessa tillsammans med en Interrupt Endpoint kanske är en lösning?

http://www.beyondlogic.org/usbnutshell/usb4.htm
http://en.wikipedia.org/wiki/Universal_Serial_Bus

Eller så skriver du en driver för en tickless linux kernel så har du tillgång till cirkus 1µs upplösning. ;)
Användarvisningsbild
GrodanB
Inlägg: 245
Blev medlem: 11 februari 2006, 16:46:25
Ort: Göteborg
Kontakt:

Inlägg av GrodanB »

Har slitit med detta tidigare... och jag kan säga att under 100ms kan man inte lita på Windows...
sodjan
EF Sponsor
Inlägg: 43249
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

Nerre> Är USB konstruerat för realtidsöverföring?

Vad är "realtid" ???

> Men det måste väl finnas någon lösning ändå som jag syftar på...

Varför måste det göra det ?
Kör du ett opertivsystem där man kan förvänta sig att det finns det ?
Det är nog just här som du har missar målet mest. Du förväntar dig
mer från den aktuella plattformen än vad den klarar (och är byggd för).

Cenorpa> Jag vill kunna överföra maximalt uppemot 0,1545Mega byte / sekund

Och det fungerar sannolikt om du kör så stora paket som möjligt, men
inte uppdelat i småpaket, och inte med ett konstant flöde med jämna intervall.

Cenorpa> Det är ingen realtidsöverföring jag är ute efter nu för det har jag insett att det inte kommer att fungera...

Och vad exakt menar *du* med "realtid" ?

Ett annat sätt vore kanske att sätta extra hårdvara som buffrar en betydligt större
del av överföringen för att sedan skicka det vidare i jämn takt.
Hur stor datavolym handlar det om totalt? Eller är det tänkt att
kunna köra under en odefinierat tid ?
Användarvisningsbild
Cenorpa
Inlägg: 737
Blev medlem: 11 juli 2005, 20:58:03
Ort: Stockholm | Borlänge
Kontakt:

Inlägg av Cenorpa »

Med realtid menar jag att det som skickas ut på USB-porten används direkt och inte buffras innan det ska användas.

Tanken är att det ska kunna köras under odefinierad tid, altså
0,1545Mega byte / sekund ska skickas ifrån datorn. Jag vill helst inte köra paket som är större än 125Byte, då detta skall lagras i en pic och jag vill hellst inte använda någon extern minneskrets. i och för sig så finns det väl mcu med större minne också
rehnmaak
Inlägg: 2204
Blev medlem: 13 december 2005, 01:43:41

Inlägg av rehnmaak »

Jág fattar det som att du vill fylla bufferten i PIC:en så fort som möjligt (125byte)? Om du styr CTS när bufferten är full så slutar FT232:an att sända direkt (om en byte håller på att sändas så kör den klart den byten). Så fort du sätter CTS igen så fortsätter flödet om det finns mer att hämta. Med andra ord kan du med hjälp av PICen styra dataflöden med hjälp av CTS, det är det som handskaningssignalerna är till för.

I andra änden (PC:n) så behöver du bara trycka på data så mycket du orkar...
sodjan
EF Sponsor
Inlägg: 43249
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

> Med realtid menar jag att det som skickas ut på USB-porten används direkt
> och inte buffras innan det ska användas.

Men det gör det ju. Det buffras internt i din applikation, det buffras i
Windows driver för USB, det buffras sannolikt i den USB-host hårdvara
som sitter i PC'n, det buffras säkert i FT232'an och det buffras (säger du själv)
i den PIC som sitter på andra sidan av FT232'an.

Med tanke på rehnmaak's kommentar så är det frågan om paketstorleken
över USB har någon betydelse alls. Sannolikt så kommer FT232'an att styra
flödet över USB efter hur dess interna buffertar är fyllda.

"Realtid" är ett av de mest missbrukade uttrycken och väldigt vanligt
när man inte har full koll på sin kravspecifikation. Att t.ex titta på
väderbilder från en vädersatelit i "realtid" kan betyda att bilderna är
10-15 minuter "gamla". När Bofors ska mäta acceleration i en
granat så gäller sannolikt helt andra definitioner av "realtid". Så summan
är att det är ett ganska värdelöst begrepp om man inte omsätter det
i hårda värden i us, ms, s, min eller vad som är rellevant i sammanhanget.
Skriv svar