Descarga este documento en formato PDF - Ucontrol
Descarga este documento en formato PDF - Ucontrol
Descarga este documento en formato PDF - Ucontrol
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( )