Página 1 de 1

Delay ou Sleep de uS ?

MensagemEnviado: 27 Jan 2009 11:15
por rodrigoevaldo
Alguém consegue informar-me se no PC é possível fazer micro temporizações na faixa de microsegundos?
O delay do DOS e o Sleep do Windows são para milisegundos.
A única forma que encontrei mas considerei anti profissional. Elaborar uma rotina de calibração ao iniciar o aplicativo toda vez, aguarda o relogio do pc mudar de segundo (tick) e iniciar um loop quase infinito até o proximo tick de segundo, assim saberei quantos laços while ou for são necessários para completar 1 segundo. Depois com uma simples regrinha dos 3, saberei a quantidade de laços por microsegundo.
Existe outra maneira mais confiável para fazer isso? A idéia principal é fazer um aplicativo para rodar no Windows.
O maior incoveniente se na calibração o usuario resolve abrir um aplicativo simultaneamente perde a referencia, ou mesmo durante a aplicação rodando o usuario resolve abrir outro aplicativo em segundo plano como por exemplo ouvir um MP3...
Pensei utilizar o relogio do PC porém a menor escala disponível são 10mS foi o formata de hora é hh:mm:ss:nn ou seja 1 segundo é dividido em 100 partes.

MensagemEnviado: 27 Jan 2009 12:54
por joao
Olha,

Não tenho nenhuma idéia em mente sobre como conseguir microsegundos. Mas gostaria de saber porque vc precisa de um contador tão baixo. Poderia explicar?

[]'s

MensagemEnviado: 27 Jan 2009 13:20
por msamsoniuk
fazer um loop nao adianta, pois o windows eh multi-thread, entao seu loop sera interrompido a qq instante e outra thread irah rodar no lugar, perdendo totalmente a precisao. a solucao depende muito do que vc precisa fazer, pq dependendo do caso, nao tem como fazer em um PC (eh para isso que existem microcontroladores! :)

MensagemEnviado: 27 Jan 2009 13:48
por rodrigoevaldo
Encontrei uns links bem interessantes, o segundo tem um programinha para DOS que considerei que funcionou com muita precisão.
Além de medir o real clock do pc, por exemplo CPU 1.8Ghz, mostrará o valor exato bem quebradinho.
E no segundo teste ele aguarda pressionar qualquer tecla para o medir o tempo como um cronometro. Fiz o pressionar as teclas bem rapidinho no qual é em torno de 80 a 250 ms, mostrou em ms e muitas casas decimais até em nanosegundos.
Assim que puder farei um teste tentar gerar um clock de 2Khz e como desafio um clock de 10Khz em um pino da porta paralela, espero que bata certinho. Se alguém poderia testar a comunidade agradece.
Vi o software TurboCNC consegue gerar clocks nesta escala de frequencia na porta paralela e porque eu não conseguiria?

http://cplus.about.com/od/howtodothingsi2/a/timing.htm
http://www.weizmann.ac.il/home/chaipi/TimeTest.htm
http://www.songho.ca/misc/timer/timer.html

A aplicação que tenho interesse é fazer um software equivalente ao TurboCNC como trabalho de faculdade, a estrutura mecanica e eletronica meu amigo concluiu.

MensagemEnviado: 27 Jan 2009 13:57
por andre_luis
Rodrigo,

Temporização na faixa de mSeg no Windows é impraticável.
O Windows é um SO multitarefa, e isso não garante a sincronia das tarefas.

O que pode ser feito ( já fiz assim e funcionou ), é voce gerar interrupçoes por HW (COM, LPT), já que essas tem prioridade no tratamento.

+++

Re: Delay ou Sleep de uS ?

MensagemEnviado: 27 Jan 2009 15:17
por polesapart
rodrigoevaldo escreveu:Alguém consegue informar-me se no PC é possível fazer micro temporizações na faixa de microsegundos?


Olha, uma vez no linux precisei fazer uma rotina que tinha um sleep de no mínimo 200 ns pra comunicar com um dispositivo via porta paralela. Como era um mínimo, eu tentei fazer com usleep(1). O problema é que o linux só dava aos processos fatias de tempo de 10 milisegundos, então o usleep(1) ficou uma carroçona e levava uma era pra completar a operação.

O que eu fiz foi o seguinte: rodei o processo com prioridade de tempo real, e lendo o /proc/cpuinfo obtia a informação relativa aos bogomips (eu tentei calibrar isto dentro do programa, e deu certo, mas ler a informação do kernel me pareceu mais interessante a epoca), que é uma referência sobre o quanto tempo instruções básicas levam para executar (abstraindo o fato que isto é estatístico num PC).

Então eu usei a instrução rdtsc para ler o time stamp counter, que é um registrador da cpu acessivel aos programas (no linux, no windows eu não sei) e que incrementa a cada ciclo de clock. Com a informação dos bogomips eu conseguia calcular o tempo de cada incremento do rdtsc e calcular o número de passagens do contador que eu precisava acompanhar, algo mais ou menos assim:

amount = ns_to_sleep / (bogomips * 1000);

x = rdtsc();
i = x + amount;
for (; x <= i; x = rdtsc());

Como o processo rodava em tempo real (tinha prioridade sobre os outros processos), eu consegui uma resolução de algumas dezenas de nanosegundos (com o clock daquele processador em particular) e uma precisão com média estatística similar a precisão. Estatística pq o processo não tinha prioridade sobre as atividades do kernel, e volta e meia os delays beiravam as centenas de micro-segundos (ou talvez beirasse 1ms, não lembro, mas era bem melhor que 10ms), mas como o que me interessava era, na média, comunicar com um delay mínimo de 200ns, funcionou maravilhosamente. Eu experimentei desabilitar interrupções mas não gostei muito do resultado.

No windows talvez dê pra fazer alguma mutreta semelhante mas o que eu recomendo é um deltree c: /y (olha lá hein, tou brincando!), se é que isto ainda funciona, pq windows ninguém merece hehehe.

Boa sorte!

MensagemEnviado: 28 Jan 2009 01:27
por msamsoniuk
tem casos e casos rodrigo...

uma vez eu consegui gerar na paralela um stream sincrono de 250kbit/s em um P166. essa velocidade foi o pico de performance da maquina e usava 2 bits, um para o stream de bits e outro para clock de sincronismo. o funcionamento, porem, nao era nada estavel. visto de um osciloscopio, apareciam bursts periodicos de quase 500KHz com pequenos gaps entre eles. para um receptor sincrono por hardware, nao seria dificil receber o stream de dados, porem para outra porta paralela amostrando seria impossivel! dependendo da aplicacao, certamente nao serve! se vc precisa de uma operacao suave, o melhor eh usar o hardware dedicado de um microcontrolador mesmo.

comparativamente, um microcontrolador de 8 bits com uma interface spi pode gerar o mesmo stream de bits a cadencias elevadas como 8 ou 16 mbit/s. e processadores avancados, como o powerpc, cujo hardware de spi possui recepcao via dma, pode tranquilamente enviar e receber streams com velocidades ainda maiores e praticamente sem nenhum jitter! mesmo coisas simples, como ativar saidas como vc citou, a 2 ou 10KHz, sao coisas simples para os timers de um microcontrolador e o sinal de saida sai muito limpo e isento das interferencias que surgem no caso do processador maior simulando.

eh ateh meio chato pensar sobre isso... um processador parrudo operando a GHz sofre para fazer em software algo que um microcontrolador de 8 bits faz direto... mas infelizmente eh assim, eh o hardware em volta do processador eh que realmente faz diferenca!

MensagemEnviado: 28 Jan 2009 07:44
por andre_luis
Infelizmente as pessoas hoje aprendem mais de SW que de HW.
A solução por interrupção de IRQ que mencionei funciona bem, mas necessita de um circuito externo á cristal.

+++