Gracias por los saludos y seguirme amigos:
en el siguiente ejemplo se realizara el clasico parpadeo de led para demostrar una simple y típica rutina para este RTOS.
expondré primero las partes de la aplicación de la configuración de los encabezados ,que son las básicas y necesarias para que el
ejemplo de los led funcione como nos parece y luego explicare funcionalidades del código + posibles variantes que resultan interesantes.

en la imagen pegue texto de color rojo para resaltar las partes necesarias para que genere el encabezado.
observaciones:
_Para,el tamaño de TasckTimer lo coloque en int (con objeto de disponer de periodos + largos de todo tipo de función temporizadora).
_la política de prioridades se des-habilito para ahorrar espacio de memoria en micro (ocurre lo contrario
al habilitarlas y + en el modo extendido)
_el resto se puede quedar como en la imagen aparece
Con respecto al código subido comenzare con el principal:
void main (void)
{
Init(); // configuración del pic
OS_Init(); // inicializacion de variables del OSA
OS_Task_Create(5, TaskParpaLedUno ); // creación de tarea con su prioridad
OS_Task_Create(5, TaskParpaLedDos ); // es decir OS_Task_Create(prioridad asignada , nombre del Task)
// que para este caso no tiene sentido x estar des-habilitada las prioridades ,pero
// se necesita que este para que el compilador no tire errores x la necesidad de datos para la función
OS_EI(); // habilita las interrupciones
OS_Run(); // arranca el kernel
}
otra variante interesante de arrancar el kernel seria:
void main (void)
{
Init();
OS_Init();
OS_Task_Create(5, TaskParpaLedUno );
OS_Task_Create(5, TaskParpaLedDos );
OS_EI();
for (;;) {
OS_Sched ();
}
}
Tiene su razón la posibilidad de arrancar de esta manera al kernel,que en otro post comentare.
sigo con la configuración para este micro:
void Init (void)
{
OSCCON=0b01110001; // Cnfg Para trabajar en 8Mhz
/********************************************************************************/
T0CS = 0; // clock select : interno/4
PSA = 0; // asignacion de entrada al oscilador interno/4
PS2 = 1; // Osc /128
PS1 = 1; //
PS0 = 0; //
T0IE = 1; // habilitar la interrupción por desborde del TMR0
/*********************************************************************************/
ADON=0;
ANSEL=0;
ANSELH=0x00;
PEIE=0;
GIE=1;
}
En esta función se puede ver que en la primera instrucción es la configuración del oscilador,que para mi parecer (en los casos de OSA RTOS)
tiene que ser la máxima frecuencia disponible (salvo aplicaciones portátiles) para poder realizar mayor cantidad de tareas a tiempo y forma.
En este caso las funciones de temporizado recaerán sobre la presicion del TMR0 ,se lo configurara para trabajar a 1ms x tick:
tick = 1/(8Mhz/4)*(256-240)*128 = 1ms~función de interrupción:
static void interrupt
isr(void)
{
if ( T0IF ) {
T0IF = 0;
OS_Timer();
TMR0=240;
}
}
En esta función (que cada 1ms se ejecuta) aparece OS_Timer(); que es en la que consta el tiempo para que el kernel (cuando se lo llame)
tome control de alguna tarea temporizada.
Y acá las estrella de esta película los task:
que si seria preemptive seria
void TaskPreemptive( void )
{
for(;;)
{
//codigo
}
}
En este caso preemptive. el kernel en cada intervalo configurado toma control del task siendo necesario o no (es decir que si no fue requerido.
El tiempo que llevo procesar el kernel peemptivo ,que por lo gral son mas grandes que los cooperativos, fue una tarea en vano para el micro )
que si seria cooperativo; Lo que cambiaría de la misma tarea seria :
void TaskCooperative( void )
{
for(;;)
{
//codigo
OS_Yield();
}
}
El punto al que quiero llegar es que si uno aplica con el debido criterio los cambios de contexto, los RTOS cooperativos son mas rápidos y eficientes
que los Preemptives ,por ser mas chicos y por ser llamarlos en cada vez que realmente se los necesita .
acá una típica tarea del OSA:
void TaskParpaLedUno ( void )
{
TRISD0=0;
for(;;)
{
RD0=!RD0;
OS_Delay(100); // 100ms
}
}
void TaskParpaLedDos( void )
{
TRISD1=0;
for(;;)
{
RD1=!RD1;
OS_Delay(300); // 300ms
}
}
Acá como única función del OSA dentro de las tareas temporizadas se utilizo OS_Delay();
En el siguiente post comentare y ejemplificare(sobre la misma plataforma) sobre tareas orientadas a eventos y temporizadas y mixtas
Saludos cordiales y espero sus comentarios y observaciones
ManuTek
