Hola,
Les comparto un Codigo generico para que puedan usar como un Sistema RTOS,
Lo he probado una y otra vez para asegurar que funcione, con este codigo de ejemplo es para que se den una idea de como realizar un RTOS, hasta eso pueden cambiar algunas cosas para usarlo para sus proyectos.
Subiré mas codigos con la misma estructura para empezar a crear nuestro propio RTOS, Aunque actualmente ya existe el Free Rtos, entre varios mas, solo hice por curiosidad, aunque si tienen alguna idea mejor para hacerlo mas dinamico, adelante.
El codigo es para un PIC16F648A, aunque los siguientes codigos seran para el PIC18F4520.
Saludos!
Les comparto un Codigo generico para que puedan usar como un Sistema RTOS,
Lo he probado una y otra vez para asegurar que funcione, con este codigo de ejemplo es para que se den una idea de como realizar un RTOS, hasta eso pueden cambiar algunas cosas para usarlo para sus proyectos.
Subiré mas codigos con la misma estructura para empezar a crear nuestro propio RTOS, Aunque actualmente ya existe el Free Rtos, entre varios mas, solo hice por curiosidad, aunque si tienen alguna idea mejor para hacerlo mas dinamico, adelante.
El codigo es para un PIC16F648A, aunque los siguientes codigos seran para el PIC18F4520.
Saludos!
Código:
/*
* File: Main.c
* Author: jorge rodriguez
*
* Created on 12 de noviembre de 2014, 04:44 PM
*
* Brief: Codigo de ejemplo de un RTOS a una velocidad de 1mS de interrupcion
*/
/*
Incluimos Librerias
*/
#include <htc.h>
#include <stdio.h>
#include <stdlib.h>
/*
Configuramos los Fuses del Microcontrolador
*/
#pragma config WDTE=OFF,PWRTE=ON,CP=OFF,BOREN=OFF,MCLRE=ON,CPD=OFF,FOSC=HS
/*
Configuramos La velocidad de trabajo del Microcontrolador
*/
#define __XTAL_FREQ 20000000
/*
Definiciones Globales
*/
#define Int_OFF PIE1bits.TMR1IE = 0
#define Int_ON PIE1bits.TMR1IE = 1
#define TimeRTOS 64911
/*
Variables del Sistema RTOS
*/
int TasksCounter=0;
unsigned int ProcessTaskFlags=0;
unsigned char flagInter=0;
/*
Variables Globales para Usuario
*/
/*
Punteros de funciones en una estructura, Aqui debe de crear tus funciones o estructuras que vas a usar en tus codigos
*/
struct Led_Control{
void (*ptr_blink) (unsigned char* port,unsigned char _nbit,int _time);
void (*ptr_Shift_Led) (unsigned char *port,int _time);
void (*Init)(void);
}Led_Control;
/*
Funciones de Escribir y Leer del Timer 1 para Sistema RTOS
*/
unsigned int ReadTimer1(){
return (unsigned int)(TMR1H<<8)|(TMR1L);
}
void WriteTimer1(unsigned int _load){
TMR1H = (unsigned int) (_load>>8)&0xFF;
TMR1L = (_load&0xFF);
}
/*
Interrupcion por Timer 1 a una velocidad de 1mS para el Sistema RTOS
*/
static void interrupt isr(){
if(PIR1bits.TMR1IF){
PIR1bits.TMR1IF=0;
flagInter = 1;
TasksCounter++;
WriteTimer1(TimeRTOS);
}
}
/*
Funciones de Usuario
*/
void blink(unsigned char* port,unsigned char _nbit,int _time){
/*
Dentro de cada Funcion debe de existir una Variable _time para
* darle tiempo de ejecucion de la tarea.
* La sentencia IF, if((TasksCounter%_time) == 0) siempre debe de estar
*/
if((TasksCounter%_time) == 0){
/*
Siempre Apage la interrupcion del Sistema RTOS antes de empezar su codigo
*/
Int_OFF;
/*
Codigo del Usuario
* Inicio
*/
(*port) ^= (1<<_nbit);
/*
Codigo del Usuario
* Final
*/
/*
Siempre Inicie la interrupción del Sistema RTOS despues de terminar su codigo
*/
Int_ON;
}
}
void Shift_LED(unsigned char *port,int _time){
/*
Dentro de cada Funcion debe de existir una Variable _time para
* darle tiempo de ejecucion de la tarea.
* La sentencia IF, if((TasksCounter%_time) == 0) siempre debe de estar
*/
if((TasksCounter%_time) == 0){
/*
Siempre Apage la interrupcion del Sistema RTOS antes de empezar su codigo
*/
Int_OFF;
/*
Codigo del Usuario
* Inicio
*/
for(unsigned char _shift=0;_shift<7;_shift++){
(*port) ^= (1<<_shift);
for(unsigned int _t=10000;_t>0;_t--);
(*port) ^= (1<<_shift);
for(unsigned int _t=10000;_t>0;_t--);
}
/*
Codigo del Usuario
* Final
*/
/*
Siempre Inicie la interrupcion del Sistema RTOS despues de terminar su codigo
*/
Int_ON;
}
}
/*
Funcion de Empezar las Tareas del Sistema RTOS
*/
void Tasks_Start(void){
Int_ON;
while(1){
if(flagInter){
flagInter=0;
/*
Aqui llama las funciones del Usuario
*/
Led_Control.ptr_blink(&PORTB,5,50); //Cada 50mS se ejecutara esta funcion
Led_Control.ptr_blink(&PORTB,0,1000); //Cada 1s se ejecutara esta funcion
Led_Control.ptr_Shift_Led(&PORTA,600); //Cada 600mS se ejecutara esta Funcion
}
}
}
void Init(void){
//Instancias de Funciones a Usar
Led_Control.ptr_blink = &blink;
Led_Control.ptr_Shift_Led = &Shift_LED;
}
/*
*
*/
void main(void) {
//Configuracion de Puertos y Perifericos
TRISB = 0x00;
TRISA = 0x00;
CMCON = 0x07;
T1CON = 0b00110001;
//Configuracion Timer1 para el Sistema RTOS a 1mS
WriteTimer1(TimeRTOS);
Led_Control.Init=&Init;
Led_Control.Init();
PORTB = 0x00;
PORTA = 0x00;
//Activa las Interrupciones Globales
INTCONbits.GIE = 1;
INTCONbits.PEIE = 1;
//Inicia Las Tareas
Tasks_Start();
}