RTOS

Başlatan HEXF2, 01 Aralık 2005, 08:18:10

picusta

Yazdigin koda bakilirsa Pin her zaman low kalacak.
Birinci Task her saniyede pini High yapmak istiyor. Nitekimde yapiyor. Ama arkadan hemen 2. Task geliyor (her 0.5 saniye, dolayisi ile her saniyede de aktif) ve pini low ediyor. Yani pin sadece birkaç mikrosaniye high kaliyor.
Halbuki yapmak istedigin 1 saniye periyotlu 2 defaze task.

CaFFeiNe

böyle bir cevap geleceğini bildiğim için 2.task taki output_low(PIN_B0); komutunu kaldırıpta denemiştim led yinede yanmadı yani 1.task işletilmiyor sanırım

2.si kendi örneği niye çalışmıyor?

bizim sonradan lisanslı :) CCS de problemmi var yoksa 3.242 versiyon

Erol YILMAZ

Ne crancki hocam, biz hep lisansli kullaniyoruz.
Lisanssizsa sizin yazilim hic konusmayalim.

picusta

Madem 18F kullaniyorsun bide PICos'u dene. C18 ile.

CaFFeiNe

18F452 örnekte olduğu için değiştirmedim
başka bir pikte olabilir önemli olan CCS de bu RTOS u nasıl,neden,niye çalıştıramadık :) bazen takıntılı oluyorum illada CCS ile çalışsın :)

picusta

Ben hiç CCS'de RTOS progrma yazmadim. Ama söyle deneyebiliriz, programi compile ettikten sonra arada olusturulan ASM kodunu inceleyebiliriz, böylece interruptta ve mainde ne yazildigini anlayabiliriz.
rtos_run() komutundan sonra sonsuz döngü gerekmiyor dimi? while(1) türü.
18F te gerçek anlamda taskler oluyor.

OxfordBlue

Alıntı yapılan: argeci - 02 Aralık 2005, 10:24:50
//multitasking system – handle multiple tasks with one microprocessor
//task counters used to tell when a task is ready to be executed
//all these counters are incremented every time a 500us interrupt happens
//every task has its own counter that is updated every time a 500us interrupt happens
unsigned int task0_counter=0;
unsigned int task1_counter=0;
unsigned int task2_counter=0;

//this tells when a task is going to happen again
//for example, when task0_counter==TASK0_COUNTER_MAX, set task0_counter=0 and do task
#define TASK0_COUNTER_MAX 1         //high frequency task – every 500us, maybe PWM
#define TASK1_COUNTER_MAX 2000      //low frequency task – every 1000ms
#define TASK2_COUNTER_MAX 5000      //low frequency and low priority task, every 2500ms

//Note: every variable referenced in both interrupt and main() must be declared volatile. You have been warned!
//this enables/disables a task
volatile unsigned char task0_enable=TRUE;
volatile unsigned char task1_enable=TRUE;
volatile unsigned char task2_enable=TRUE;

//this allows tasks triggered by interrupt to run in the background in main()
volatile unsigned char task2_go=FALSE;
void setup_multitasking(void)
{
   //set up tmr1  to interrupt every 500us
   TMR1CS=0;
   T1CKPS0=0;
   T1CKPS1=0;

/*We want to wait 2000 clock cycles, or 500us @ 16MHz (instructions are 1/4 speed of clock).  Timer 1 interrupts when it gets to 0xFFFF or 65535.  Therefore, we set timer 1 to 65535 minus 2000 = 63535, then wait 2000 ticks until rollover at 65535.  To test, use simulator to find that its exactly correct*/

   #define  TICKS_BETWEEN_INTERRUPTS      2000
   #define  INTERRUPT_OVERHEAD            19
   #define TMR1RESET (0xFFFF-(TICKS_BETWEEN_INTERRUPTS-INTERRUPT_OVERHEAD))
   #define TMR1RESET_HIGH TMR1RESET >> 8
   #define TMR1RESET_LOW TMR1RESET & 0xFF
   TMR1ON=0;
   TMR1H=TMR1RESET_HIGH;
   TMR1L=TMR1RESET_LOW;
   TMR1ON=1;      
   TMR1IF=0;
   TMR1IE=1;
   PEIE=1;
   GIE=1;   
}

void interrupt isr(void)
{
   //one tick every 500us at 16Mhz
   if (TMR1IF)
   {
      //set up timer 1 again to interrupt 500us in future
      TMR1IF=0;
      TMR1ON=0;
      TMR1H=TMR1RESET_HIGH;
      TMR1L=TMR1RESET_LOW;
      TMR1ON=1;
      task0_counter++;
      if (task0_counter>=TASK0_COUNTER_MAX)     //high frequency task – every 1 tick
      {
            task0_counter=0;
            if (task0_enable==TRUE)
            {
                  //do high frequency important task 0, for example PWM
            }
      }
      task1_counter++;
      if (task1_counter>=TASK1_COUNTER_MAX)     //low priority task - every 2000 ticks
      {
            task1_counter=0;
            if (task1_enable==TRUE)
            {
                  //do low frequency yet important task 1
            }
      }

/*this task takes a long time, 100ms for example, lots of maths.  Is extremely low priority, but has to be done at regular intervals, so all this does is trigger it.  In main(), it will, at leisure, poll ‘task2_go' and then execute it in the background.*/

      task2_counter++;
      if (task2_counter>=TASK2_COUNTER_MAX)     //every 250ms
      {
          task2_counter=0;
          if (task2_enable==TRUE)
          {
               //every 250ms take 100ms to do maths, do this in main() so the we can get back to doing the high frequency tasks.
               task2_go=TRUE;
          }
      }
   }  //if (TMR1IF)
} //interrupt routine


main()
{
   setup_multitasking();
   while(1)
   {
      if (task2_go==TRUE)
      {
            task2_go=FALSE;
            //take our time, doing heaps of complex maths at our leisure in the background
      }
   }
}

şimdi yukardaki koda beraber bakarsak 500us de task0 var pwm için
1sn (1000ms) task1
ve daha yüksek zamanlar için 2500 ms lik task2
interupt rutini sana bu olayı düzenliyo 500us kurulmuş timer interupu her 500us de task 0 countu 1 olduğu için hemen true oluyo maine bakarsan task 0 ve bir için kod yok eğer sen
          task0_counter=0;
          if (task0_enable==TRUE)
          {
          }
desydin 500usde bir işlemesi gereken kodlarını buraya yazardın örnek task2 yi almış interrupt programı her 500us'de bir task2 nin counter değerini bir arttıracak taki 5000 olana kadar yani 2,5 saniye olana dek  2,5 saniye geçmeden task2_enable true olmayacak ve senin o if'in içindeki kod çalışmayacak eğer sen bu if'in içinde toogle (pinb1); yazsan ve b1'e led bağlasan 2,5 saniyede yanıp sönen bir led elde ederdin eğer bu kodu task 1 le değiştirsen 1 saniyede task0 ile değiştirsen ledin her 500us de konum değiştirecekti
İşte mesele bundan ibaret rtoslarda buna benzer bi yapı ile çalışıyor bazı rtoslar dahada gelişmiş öncelik verebiliyosun zaman dışında bazı şartlarada bağlayabiliyorsun 
http://www.bknd.com/cc5x/multitasking.shtml
buralara
http://freertos.org 'a ve 
http://www.picos18.com/index_us.htm 'ada bakabilirsin ben biraz genel değindim kalanını siz tamamlarsınız inşallah

Bu örnekteki gibi time scaling işlemi yapabiliyorum. bu işlem rtosu biliyorum demek için yeterlimidir ? yoksa rtos oluşturmak için başka ne yapmak gerekir.