20.04.2013 Views

Descarga este documento en formato PDF - Ucontrol

Descarga este documento en formato PDF - Ucontrol

Descarga este documento en formato PDF - Ucontrol

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

18 de 22<br />

utilice <strong>en</strong> las técnicas de programación anterior porque la ejecución secu<strong>en</strong>cial del código presupone que no se<br />

requiera de un mecanismo como <strong>este</strong>.<br />

Lo más cercano al método descrito <strong>en</strong> el poner datos <strong>en</strong> algún lugar para que una función lo procese es el uso<br />

de las interrupciones, éstas deb<strong>en</strong> procesar rápidam<strong>en</strong>te el ev<strong>en</strong>to de interrupción y pude que pongamos el<br />

dato <strong>en</strong> algún lugar y levantemos una bandera para que cuando a la función <strong>en</strong>cargada de procesar los datos<br />

le toque ejecutarse lea la bandera, procese los datos y coloque la bandera <strong>en</strong> el estado que notifica que ya se<br />

procesó, no para notificar a otra función sino para notificárselo a ella misma, no vaya a ser que cuando le<br />

toque ejecutarse nuevam<strong>en</strong>te procese los mismos resultados nuevam<strong>en</strong>te o haga algo indebido.<br />

Un ejemplo de lo anterior puede se el uso del conversor AD, <strong>en</strong> algún lugar del programa lo mandamos a<br />

convertir; una vez hecha la conversión se produce una interrupción que es at<strong>en</strong>dida <strong>en</strong> la correspondi<strong>en</strong>te<br />

subrutina de at<strong>en</strong>ción a esa interrupción; leemos el dato lo ponemos <strong>en</strong> una variable e increm<strong>en</strong>tamos un<br />

contador. Posteriorm<strong>en</strong>te le toca ejecutarse a la función que promedia los resultados, ésta comprueba si hay,<br />

digamos 200 muestras, si las hay hace el cálculo que pone <strong>en</strong> otra variable y deja el contador <strong>en</strong> cero. Este<br />

mecanismo es eficaz porque se ha utilizado durante mucho tiempo, pero los RTOS brindan una solución<br />

elegante para hacer esto <strong>en</strong> el contexto de la ejecución de tareas.<br />

Estos mecanismos pued<strong>en</strong> funcionar también <strong>en</strong>tre funciones pero t<strong>en</strong>dremos el problema de tratar con un montón de<br />

estructuras de datos, banderas y contadores, complejas expresiones lógicas a procesar… ¿se acuerdan de eso?<br />

Ahora imagín<strong>en</strong>se hacer todo lo anterior cuando, <strong>en</strong> vez de llamadas a funciones metidas d<strong>en</strong>tro de un código<br />

que se ejecuta más o m<strong>en</strong>os estructuradam<strong>en</strong>te, lo que t<strong>en</strong>emos es unas cuantas tareas de las que no<br />

t<strong>en</strong>emos un control de cuando ni como se ejecutarán. Realm<strong>en</strong>te puede ser una verdadera pesadilla hacer un<br />

programa productivo, y es por ello que los RTOS nos ofrec<strong>en</strong> un poderoso mecanismo para hacer eso, y como<br />

siempre, <strong>este</strong> mecanismo también es relativam<strong>en</strong>te simple.<br />

Para hacer lo anterior los RTOS implem<strong>en</strong>tan un mecanismo de m<strong>en</strong>sajes. Sí, amigos míos, un RTOS<br />

implem<strong>en</strong>ta una función similar a la de los correos.<br />

El funcionami<strong>en</strong>to de ese mecanismo es simple, cuando una tarea o subrutina de at<strong>en</strong>ción a interrupciones<br />

necesita notificarle algo a otra tarea llama a una función que pone el dato <strong>en</strong> la cola de la tarea <strong>en</strong> cuestión,<br />

cuando a la tarea que recibió el m<strong>en</strong>saje le toca ejecutarse debe, <strong>en</strong> algún lugar consultar su cola de<br />

m<strong>en</strong>sajes, si hay m<strong>en</strong>sajes debe leerlos y procesarlos, como pued<strong>en</strong> ver <strong>este</strong> mecanismo es bastante parecido<br />

a lo que hacemos habitualm<strong>en</strong>te.<br />

Si yo quiero pasarles un m<strong>en</strong>saje, por ejemplo un post, hago lo sigui<strong>en</strong>te:<br />

- lo escribo, <strong>este</strong> es el equival<strong>en</strong>te a realizar una tarea<br />

- lo mando al foro, <strong>este</strong> es el equival<strong>en</strong>te a ponerlo <strong>en</strong> la cola de m<strong>en</strong>sajes del hilo sobre RTOS<br />

- ustedes llegan y consultan si hay m<strong>en</strong>sajes nuevos <strong>en</strong> el hilo, por supuesto llegan cuando su tarea de leer el<br />

foro está activa<br />

- si hay un m<strong>en</strong>saje nuevo, normalm<strong>en</strong>te tratarán de leerlo y poner <strong>en</strong> práctica los nuevos conocimi<strong>en</strong>tos<br />

- si se si<strong>en</strong>t<strong>en</strong> impresionados, me escribirán un m<strong>en</strong>saje a mi correo privado, dándome un acuse de recibo (no<br />

hagan esto si no es estrictam<strong>en</strong>te necesario, no vaya a ser que me vuelvan loco)<br />

Aquí se ha puesto de manifiesto un ejemplo del sistema de m<strong>en</strong>sajes más simple utilizado por un SO: elaborar<br />

y <strong>en</strong>viar de una parte y consultar si hay un m<strong>en</strong>saje, procesar y <strong>en</strong>viar acuse de recibo si es necesario de la<br />

otra parte.<br />

(Todo esto está muy bi<strong>en</strong>. Pero yo quiero código y ejemplos de verdad.)<br />

Vale, no nos ofusquemos, primero <strong>en</strong>t<strong>en</strong>der bi<strong>en</strong> el concepto, luego ponerlo <strong>en</strong> práctica.<br />

Lo primero que t<strong>en</strong>emos que hacer es decirle al compilador que le cree una cola de m<strong>en</strong>sajes a aquella tarea a<br />

la cual queremos pasarle m<strong>en</strong>sajes, para eso t<strong>en</strong>emos el parámetro queue, d<strong>en</strong>tro de la directiva #task, con<br />

<strong>este</strong> parámetro le indicamos al RTOS que reserve memoria y cree una cola de m<strong>en</strong>sajes para la tarea, la<br />

declaración de una tarea con cola de m<strong>en</strong>sajes sería como sigue:<br />

El código:<br />

#task(rate = 1s, max=20ms, queue=5)<br />

void Tarea1(void);<br />

En la declaración de la tarea el parámetro queue = 5, le dice al compilador que cree una cola de 5 bytes para<br />

la Tarea1.<br />

Para el <strong>en</strong>vío y recepción de m<strong>en</strong>sajes t<strong>en</strong>emos las sigui<strong>en</strong>tes funciones:<br />

RTOS_MSG_SEND( )<br />

RTOS_MSG_POLL( )<br />

RTOS_MSG_READ( )

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!