Programación General > Visual C++
Timers
JuanK:
--- Cita de: "Eternal Idol" --- Tu solucion iria bien pero me parece que el problema es diferente, no quiere obtener una lista de valores e imprimirlos sino mantener un valor actualizado (solo) en la pantalla. Al menos es lo que entendi yo, si fuera asi es mejor hacerlo con varios hilos encargados de cada tarea, siempre tendria un delay en la parte de output pero el input del PIC siempre llegaria a completarse. Si es que necesita obtener muchos valores y despues imprimirlos es mejor hacerlo como decis, obtenerlos todos en un bucle, almacenarlos y finalmente procesarlos.
--- Fin de la cita ---
Claro, todo depende de que es lo que necesite, hacer algo como lo que le sugeriste a una persona la otra vez puede ser muy util.
carmamezo:
Hola a todos!
Pues creo que la mejor solución al problema es el siguiente:
Como bien dice Eternal idol parece más un problema de threads que de temporizadores, se puede controlar el tiempo de nuestro programa (más o menos) pero no podemos controlar el tiempo que tardan en ejecutarse las rutinas de escritura en pantalla...
Parece que es un problema de ejecución en tiempo real, bueno, pues para solucionar este tipo de problemas se utiliza la ejecución en paralelo como decía el compañero antes citado pero además se debe agregar un sistema de prioridades.
Por partes, lo primero es separar el código que se encarga de realizar la lectura de datos del puerto del que se dedica a escribirlos en pantalla. Para ello deberíamos realizar dos hilos, uno principal, que se encarga de mostrar los datos en pantalla y otro que se encarga de la lectura de datos del puerto. Este último hilo debe tener la prioridad más alta del sistema operativo (en el caso de windows, la prioridad 32), este hilo ejecutará un bucle hasta que desde el hilo principal se le envie una orden de fin.
Se debe realizar un Sleep() al final del bucle para liberar la CPU y dejar que otros procesos puedan pugnar por acceder a sus recursos. Para realizar un control óptimo se debe medir el tiempo que tarda el bucle en ejecutarse mediante uso de temporizadores multimedia y luego restar este tiempo a los 50ms que se desean esperar para realizar una espera del tiempo exacto, o simplemente disparar el hilo mediante temporizadores, las funciones para manejo de temporizadores multimedia son las siguientes:
timeGetDevCaps()
timeBeginPeriod()
timeSetEvent()
timeKillEvent()
timeEndPeriod()
Si lo que queremos es medir cuánto tiempo tarda en ejecutarse nuestro código (tiempo real) podemos usar los contadores de alta resolución de windows:
QueryPerformanceCounter()
QueryPerformanceFrequency()
Estos contadores tienen una resolución de micro segundos y utilizan una resolución de 64bits.
Para la modificación de la prioridad de los hilos se usan las siguientes funciones:
SetThreadPriority()
SetThreadPriorityBoost()
SetThreadPriority() debe recibir como parámetro THREAD_PRIORITY_TIME_CRITICAL previa modificación de la prioridad del proceso padre que lo crea mediante la función SetPriorityClass() pasándole a esta última función este parámetro: REALTIME_PRIORITY_CLASS.
Mucho ojo con jugar con las prioridades de hilos y procesos, dos hilos con prioridad máxima en el SO ejecutando ambos dos bucles infinitos dejan al sistema operativo totalmente bloqueado.
El proceso sería el siguiente:
- Iniciar el programa principal, llamar a la función SetPriorityClass() y pasarle el valor REALTIME_PRIORITY_CLASS. (nuestro proceso se ejecutará con prioridad 24).
- Llamar al hilo que se encarga de leer datos del puerto USB mediante un temporizador multimedia, timeSetEvent(), o bien crear el hilo.
- Llamar a la función SetThreadPriority() y pasarle el valor THREAD_PRIORITY_TIME_CRITICAL para que nuestro hilo se ejecute con prioridad 32.
- Si se opta por crear el hilo, ejecutar un bucle infinito en su interior con un Sleep() al final (NO OLVIDAR REALIZAR UNA ESPERA ACTIVA PARA NO BLOQUEAR EL SISTEMA OPERATIVO), calculando el tiempo a esperar como 50ms menos el tiempo que ha estado ejecutándose el hilo (medido mediante los contadores de alta resolución antes citados).
- Utilizar un array de tipo FIFO circular para la comunicación con el hilo principal y posibilitar al hilo principal escribir los datos en pantalla.
Lo bueno de los hilos con alta prioridad es que acaparan la CPU en cuanto esta se libera, apenas hay retraso desde que se realiza una petición para usar la CPU y se consigue la misma.
En fin, siento el rollo, SUERTE!!!!!
un saludo. :lightsabre:
carmamezo:
Se me olvidaba..... el temporizador de máxima resolución del PC es el RDTSC que es un contador que se ejecuta dentro de la propia CPU de Intel, tiene una resolución de 64 bits y utliza los registros EDX:EAX para dejar el resultado del conteo. La instrucción ensamblador de este contador es 0F 31 en hexadecimal:
--- Código: Text --- __int64 tiempo_init = 0,tiempo_fin=0; __asm{_emit 0x0F;_emit 0x31;MOV DWORD PTR tiempo_init, EAX;MOV DWORD PTR tiempo_init+4, EDX;} Sleep (100); __asm{_emit 0x0F;_emit 0x31;MOV DWORD PTR tiempo_fin, EAX;MOV DWORD PTR tiempo_fin+4, EDX;} //ciclos = tiempo//microsegundos = tiempo / frecuencia CPU (en MHZ)printf("Tiempo supuesto: 100ms");printf("\nTiempo real: %016I64ms", (tiempo_fin-tiempo_init)/1800000); //SUPONIENDO QUE LA CPU TRABAJE A 1800MHZ Un saludo. :lightsabre:
Eternal Idol:
Si es un problema de ejecucion en tiempo real entonces hay que usar un S.O. que lo permita y no Windows.
Eternal Idol:
En cuanto al RDTSC creo que la Wikipedia explica bien las razones para no usarlo:
http://en.wikipedia.org/wiki/RDTSC
Navegación
[#] Página Siguiente
[*] Página Anterior
Ir a la versión completa