Duda con cambio de contexto en FreeRTOS y lpc1769

242 views
Skip to first unread message

Federico Coppede

unread,
Nov 6, 2014, 9:57:14 AM11/6/14
to embeb...@googlegroups.com
Buenos dias a todos, tengo una duda sobre los tiempos es freertos, paso a explicar 
en mi programa tengo que tomar muestras de un adc a 40khz (es decir cada 25us) lo cual hago desde una interrupcion de timer (la lectura del adc es en paralelo por lo que es muy rapida), lo que nose, es si lo mas conveniente seria hacer el procesamiento de cada muestra (filtrado y puesta en pantalla) desde la ISR del timer, o con cada muestra desbloquear una tarea que lo haga, en ese caso, podria estar perdiendo muestras por el delay del cambio de contexto? hay alguna forma de medir ese tiempo? por que en internet no encontre informacion al respecto, se que depende obviamente de la frecuencia del micro (lpc1769) que en mi casa son 120mhz y de la configuracion del archivo freertosconfig.h (chequeo de stack overflow, etc), para que quede mas claro, con procesamiento de la señal me refiero a pasar cada muestra por un filtro fir de orden bajo, digamos 10 como mucho, y mandarla por spi a un display tft....
Muchas gracias,..
Federico.

Ulises

unread,
Nov 6, 2014, 10:48:37 AM11/6/14
to embeb...@googlegroups.com
Buenas,
Por regla general, la ISR debe ser acotada y cumplir una tarea específica.
En tu caso, adquirís las muestras, alimentás  un buffer circular y en el mejor de los casos, aplicás también el filtro FIR si te dan los tiempos.
El valor de salida del FIR lo pondrías en una cola de mensajes para que otras tareas de niveles más altos hagan lo suyo.

Si los tiempos no dan para los cálculos del FIR dentro de la ISR, el filtro debería implementarse en otra tarea de menor prioridad.
La comunicación ISR - FIR se desacopla mediante colas de mensajes.
 
Para medir tiempos de ejecución fijate que hay un hilo con asunto "Contador de ciclos de clock en Cortex-M" que podría servirte. Y si no, la típica de mover una patita y medir con el osciloscopio.

Saludos!

Ulises.

El 06/11/14 a las 11:57, Federico Coppede escibió:
--
-- Recibiste este mensaje porque estás suscripto al Grupo Google Embebidos32. Para postear en este grupo, escribe un email a embeb...@googlegroups.com. Para des-suscribirte, envía un email a embebidos32...@googlegroups.com. Para más opciones, visita el sitio del grupo en https://groups.google.com/d/forum/embebidos32?hl=es
---
Has recibido este mensaje porque estás suscrito al grupo "Embebidos32" de Grupos de Google.
Para anular la suscripción a este grupo y dejar de recibir sus mensajes, envía un correo electrónico a embebidos32...@googlegroups.com.
Para acceder a más opciones, visita https://groups.google.com/d/optout.

Agustin Alba Chicar

unread,
Nov 7, 2014, 7:09:00 AM11/7/14
to embeb...@googlegroups.com
Estimado Federico:
Te cuento que en mi experiencia para medir los tiempos de procesamiento con el mismo micro hice dos cosas que me funcionaron para situaciones distintas. En el caso que sepas a priori que tu código tarda bastante la solución de togglear un puerto y medir dicho pulso con el osciloscopio es más que apropiada como una solución rápida y para tener idea rápido del tiempo que tarda tu código en ejecutarse. Algo apropiado también para hacer es tocar directamente el registro del puerto para que esto sea más rápido (FIOPIN).

Por otro lado, podrías correr otro timer que se mueva por el mismo clock del micro. Esto lo que te permite es poder tomar directamente con la precisión de tu clock la medición de tiempo de ejecución del código. El timer no lo corrás por interrupción. Sino que simplemente como contador sincronizado con el clock.

Otra cuestión para que puedas mejorar los tiempos de ejecución de tu código, una vez validado y que estés seguro que funciona, es compilarlo con las opciones optimización. En mi caso, la opción de optimización de nivel 2 es la que mejor relación velocidad, memoria de código y de RAM me dio.

Suerte con eso.
Saludos.

Federico Coppede

unread,
Nov 7, 2014, 8:00:06 AM11/7/14
to embeb...@googlegroups.com
Buenos dias Agustin y Ulises, muchas gracias por las ideas, voy a ver si puedo medir los tiempos de ejecución, cambio de contexto y  procesado de la señal para ver si se puede llegar a hacer "en tiempo real",...

Saludos, 
Federico.

Jaime Andrés Aranguren Cardona

unread,
Nov 7, 2014, 8:15:31 AM11/7/14
to embeb...@googlegroups.com
Respecto al tema tiempo real:

Suponiendo que necesitas hacer el procesamiento de una manera "streaming" muestra in / muestra out que _no_ debe detenerse, si no podes procesar une muestra dentro de la ISR en el tiempo necesario, menos que vas a poder hacerlo cambiando de contexto, etc.

Es decir, si el tiempo de procesamiento de una muestra es mayor que el periodo de muestreo, no vas a poder hacer esto en tiempo real.

Si el sistema soporta latencia, un mecanismo más eficiente es hacer procesamiento por bloques (FFT es un caso típico de este tipo) en el cual se captura no una muestra, se procesa y se obtiene una muestra de salida, sino que se captura un bloque de datos, una vez capturados se procesan en bloques, mientras se sigue capturando otro bloque de datos en otro espacio de memoria. Idealmente usar DMA, si se soporta. Con un esquema así lo que haces es crear un pipeline entre la captura de un bloque de datos y el procesamiento del bloque de datos anterior; si se usa DMA, la captura de un bloque datos ocurre independientemente del procesamiento conl a CPU del bloque de datos anterior, efectivamente utilizando la CPU para procesar datos, no para moverlos de acá para allá.

Si en un esquema así tampoco llegas a tiempo real, mucho menos va a funcionar con un RTOS por debajo, cambiando de contexto, etc.

Una vez verificado que el sistema en efecto puede procesar tus datos en tiempo real con un solo hilo de ejecución, podés pensar en pasar a analizar si es capaz de hacer lo mismo con un (RT)OS.

Saludos

Jaime Andrés Aranguren Cardona

unread,
Nov 7, 2014, 8:46:03 AM11/7/14
to embeb...@googlegroups.com


Am Freitag, 7. November 2014 14:15:31 UTC+1 schrieb Jaime Andrés Aranguren Cardona:
Respecto al tema tiempo real:

Suponiendo que necesitas hacer el procesamiento de una manera "streaming" muestra in / muestra out que _no_ debe detenerse, si no podes procesar une muestra dentro de la ISR en el tiempo necesario, menos que vas a poder hacerlo cambiando de contexto, etc.

Es decir, si el tiempo de procesamiento de una muestra es mayor que el periodo de muestreo, no vas a poder hacer esto en tiempo real.

Si el sistema soporta latencia, un mecanismo más eficiente es hacer procesamiento por bloques (FFT es un caso típico de este tipo) en el cual se captura no una muestra, se procesa y se obtiene una muestra de salida, sino que se captura un bloque de datos, una vez capturados se procesan en bloques, mientras se sigue capturando otro bloque de datos en otro espacio de memoria. Idealmente usar DMA, si se soporta. Con un esquema así lo que haces es crear un pipeline entre la captura de un bloque de datos y el procesamiento del bloque de datos anterior; si se usa DMA, la captura de un bloque datos ocurre independientemente del procesamiento conl a CPU del bloque de datos anterior, efectivamente utilizando la CPU para procesar datos, no para moverlos de acá para allá.

Me faltó decir:

Obviamente, si el tiempo que el sistema se demora en procesar un bloque de datos es mayor que el periodo de muestreo multiplicado por el número de muestras en el bloque de datos, ya estás por fuera de tiempo real. Repito: en el caso de una aplicacion tipo streaming como por ejemplo, filtrado en aplicaciones de audio. comunicaciones, etc.

Ahora, releyendo el mensaje original, veo que el sistema es para hacer filtrado _y puesta en pantalla_. En este caso, el requerimiento de tiempo real está dado por la puesta en pantalla, no por el periodo de muestreo de la senal. Es decir para el filtrado de N muestras tenés 40 ms (asumiendo un frame rate en tu display de 25 fps, que para el ojo humano es tiempo real), no N x 25 us que sería el caso si la salida de tu sistema fuera la senal filtrada (lo que yo llamaba una aplicacion tipo streaming). En otras palabras, mientras el filtrado de N datos (y puesta en pantalla, claro) demore menos de 40 ms, vás a estar en tiempo real. Con estos datos -asumiendo que el tiempo en poner en pantalla los datos procesados es ínfimo-, si N es 1600 (40 ms / 25 us), no solo vás a estar en tiempo real, sino tambien mostrando la senal _completa_ en tiempo real; si N es menor que 1600, vás a mostrar solo _segmentos_ de la senal. Habrá que ver si tu CM3 es capaz de filtrar 1600 datos en 40 ms, lo que equivale a 25 us. Que coincidencia: exactamente el periodo de muestreo de tu ADC!!!

Queda claro como todo concuerda?

Otro punto es como se van a mostrar los datos. Asumiendo que tu CM3 es capaz de filtrar una muestra de tu senal en menos de 25 us, igual, no creo que se pueda hacer un plot de 1600 datos en un LCD del tipo que se usaría en un MCU (se necesitaría una resolucion de por lo menos 1600 pixels en alguna de las direcciones -la del eje X-, asumiendo usar la pantalla completa). Conclusión: no podés mostrar tu senal _completa_ y _en tiempo real_ en un display de menos de 1600 pixels de resolucion en alguna de las direcciones, lo cual no harías con un MCU. O si lo haces con un display "MCU-friendly", vas a tener menos datos por mostrar, por lo cual, para mostrar la senal completa (no segmentos de la misma) en tiempo real, necesitarás refrescar más rápido (aumentar el frame rate), pero si lo haces a un frame rate tan alto que el ojo humano no alcance a detectarlo, estás botando recursos = botando dinero. E igual, habrá que ver cual es el frame rate que la pantalla en cuestión es capaz de alcanzar.

Es decir: tus requerimientos de tiempo real están dados por el frame rate de la pantalla, la resolucion de la misma, y el numero de muestras que querés mostrar en un pantallazo.

Saludos
Reply all
Reply to author
Forward
0 new messages