OSA RTOS (PIC’ler için işletim sistemi)(C18 için bir çalışma)

OSA RTOS (PIC’ler için işletim sistemi)(C18 için bir çalışma)

RTOS = real time operating system = gerçek zamanlı işletim sistemi

İşletim sistemi dediysek”…heee başlat menüsü var mausla tıklıyoruz internete giriyoruz, oyun felan oynuyoruz” diye düşünmeyin.

PIC Mikrodenetleyiciden bahsediyoruz, yani bilgisayarınızdaki işlemci ve çevresel birimleri bir okyanus ise PIC olsa olsa bir su birikintisidir. İşletim sisteminin bize yapacağı en iyi kıyak, kodlarımızı thread dediğimiz işlem parçalarına ayırarak, sanki aynı anda bir kaç fonksiyon birden birbirinden bağımsız çalışıyormuş gibi göstermesidir.

3 adet lediniz var birincisini 2,3 saniyede bir yakmak istiyorsunuz, ikincisini 1.6 saniyede bir yakmayı, üçüncü ledi ise 7,9 saniyede bir yakmayı istiyorsunuz. Bu bütün işlemleri tek bir thread ile yapmaya kalkarsanız işin içinden zor çıkarsınız, aslında bu örnek için rahatlıkla halledebilirsiniz ancak bu sadece temsildir, komplex projelerde saç baş yoldurabilir. Konuya dönecek olursak, aşağıdaki üç ayrı fonksiyon, sanki 3 ayrı program yazmışız gibi işletilir. Bu sayede, ledleri, hiç kafa yormadığımız halde gönlümüzce yakıp söndürebileceğiz.

void birinci_led (void)
{
    for (;;)
    {
        LATCbits.LATC1^=1; //birinci led
        OS_Delay(2300 ms);
    }
}

void ikinci_led (void)
{
    for (;;)
    {
        LATCbits.LATC2^=1; //ikinci led
        OS_Delay(1600 ms);
    }
}

void ucuncu_led (void)
{
    for (;;)
    {
        LATCbits.LATC3^=1; //üçüncü led
        OS_Delay(7900 ms);
    }
}

Aslında yukarıdaki verdiğimiz örnek sadece programın bizi ilgilendiren kısımlarıydı. Programın arka planda çalışan bir kütüphanesi var.

anadosyamız:

 /*
  ************************************************************************************************
  *
  *  OSA example:   Running lights
  *
  *  URL:           http://wiki.pic24.ru/doku.php/en/osa/ref/intro
  *                 http://picosa.narod.ru
  *
  *----------------------------------------------------------------------------------------------
  *
  *  File:          lights_mikroc.c
  *
  *  Compilers:     Microchip C18
  *
  *  Controller:    PIC18F252
  *
  *  Programmer:    Timofeev Victor
  *                 osa@pic24.ru, testerplus@mail.ru
  *
  *  Description:   This is simple program written with RTOS OSA.
  *                 There are eight LEDs controlled by the program. The program
  *                 changes brightness of each LED and changes it in time.
  *
  ************************************************************************************************
  */

#include <osa.h>
#include <p18f252.h>

#pragma config WDT = OFF
#pragma config OSC = HS 
#pragma config LVP = OFF
#pragma config BOR = OFF

//******************************************************************************
//  
//      Constants
// 
//******************************************************************************

#define PORTA_CONST     0x00
#define TRISA_CONST     0x01

#define PORTB_CONST     0x00
#define TRISB_CONST     0x01

#define PORTC_CONST     0x00
#define TRISC_CONST     0x00

#define pin_BUTTON      PORTBbits.RB0
#define PORTLEDS        PORTC

#define NUMBER_OF_LEDS  8
#define TABLE_MASK      7

//------------------------------------------------------------------------------
// Timers
//------------------------------------------------------------------------------

// Timer0 used as a counter for software PWM

#define T0CON_CONST     0x41        // prs = 4 (period = 256 * 4 * 0.2us = 200 us)
                                    // 8-bit mode
// TImer2 used for system ticks

#define T2CON_CONST     0x25        // post = 8, period = 250*4*5* 0.2 us = 1 ms
#define PR2_CONST       (250-1)     
#define ms              / 1         // 

//****************************************************************************** 
// 
//      LED's brightness table
// 
//****************************************************************************** 

//------------------------------------------------------------------------------
#if     NUMBER_OF_LEDS == 4
//------------------------------------------------------------------------------
    const char Brightness[] = {31, 11,  4,  0};
//------------------------------------------------------------------------------
#elif   NUMBER_OF_LEDS == 8
//------------------------------------------------------------------------------
    const char Brightness[] = {31, 20, 11,  7,  4, 2, 1, 0};
//------------------------------------------------------------------------------
#else
//------------------------------------------------------------------------------
    #error "Incorrect NUMBER_OF_LEDS constant value (should be 4 or 8)"
//------------------------------------------------------------------------------
#endif
//------------------------------------------------------------------------------

//******************************************************************************
//  
//      Global variables
// 
//******************************************************************************

volatile char   m_ucSpeed;       // Rotation speed
volatile char   m_ucPosition;    // Current rotation phase (position of brightness value in 
                                // Brightness table) 
volatile char   m_scDirection;   // Rotation direction (-1, +1)

//******************************************************************************
//  
//      Function prototypes
// 
//******************************************************************************

void    Init (void);
void    birinci_led (void); //Task_Rolling
void    ikinci_led (void); //Task_SetSpeed
void    ucuncu_led (void); //Task_Button

/********************************************************************************
 *                                                                              *
 *  Function:       main                                                        * 
 *                                                                              *
 *------------------------------------------------------------------------------* 
 *                                                                              *
 ********************************************************************************/

void main (void)
{
    Init();                             // Init periphery

    OS_Init();                          // Init OS

    OS_Task_Create(0, birinci_led);    // Create tasks.
    OS_Task_Create(0, ikinci_led);     //
    OS_Task_Create(0, ucuncu_led);     //

                                        // Starting values:
    m_ucPosition  = 0;                  // rotation phase
    m_scDirection = 1;                  // dircetion

    OS_EI();                            // Enable interrupts

    OS_Run();                           // Running scheduler

}

/********************************************************************************
 *                                                                              *
 *  Function:       Init                                                        *
 *                                                                              *
 *------------------------------------------------------------------------------* 
 *
 *  description:    Makes periphery initialization:
 *                  - I/O ports
 *                  - ADC
 *                  - timers
 *                  - interrupts
 *
 *  parameters:     void
 *
 *  on return:      void
 *
 ********************************************************************************/

void Init (void)
{

    //------------------------------------------------------------------------------
    //  I/O ports configuration
    //------------------------------------------------------------------------------

    PORTA = PORTA_CONST;
    PORTB = PORTB_CONST;

    TRISA = TRISA_CONST;
    TRISB = TRISB_CONST;

    INTCON2bits.RBPU = 0;

    #if defined(PORTC_CONST)
        PORTC = PORTC_CONST;
        TRISC = TRISC_CONST;
    #endif

    #if defined(PORTD_CONST)
        PORTD = PORTD_CONST;
        TRISD = TRISD_CONST;
    #endif

    #if defined(PORTE_CONST)
        PORTE = PORTE_CONST;
        TRISE = TRISE_CONST;
    #endif

    //------------------------------------------------------------------------------
    //  ADC
    //------------------------------------------------------------------------------

    ADCON0 = 0xC1;                  // Channel 0
                                    // ADON = 1
                                    // Fosc/32

    ADCON1 = 0x0E;                  // Use only one analog input AN0 (RA0)
                                    // Left justify

    //------------------------------------------------------------------------------
    //  Timers init
    //------------------------------------------------------------------------------

    T0CON = 0x80 | T0CON_CONST;

    T2CON = T2CON_CONST;
    PR2 = 250-1;

    //------------------------------------------------------------------------------
    //  Interrupts
    //------------------------------------------------------------------------------

    INTCON = 0;
    INTCONbits.T0IE = 1;
    INTCONbits.PEIE = 1;
    PIE1bits.TMR2IE = 1;
}

/********************************************************************************
 *
 *  Interrupts service routine
 *
 ********************************************************************************/
void interrupt_high (void);

//----------------------------------------------------------------------------
// High priority interrupt vector

#pragma code InterruptVectorHigh = 0x08
void
InterruptVectorHigh (void)
{
  _asm
    goto interrupt_high //jump to interrupt routine
  _endasm
}

//----------------------------------------------------------------------------
// High priority interrupt routine

#pragma code
#pragma interrupt interrupt_high

void interrupt_high (void)
{    
    if (INTCONbits.T0IF && INTCONbits.T0IE)
    {
        INTCONbits.T0IF = 0;

    }

    //******************************************************************************
    //  System timer (for system ticks)
    //******************************************************************************

    if (PIR1bits.TMR2IF)
    {
        PIR1bits.TMR2IF = 0;
        OS_Timer();
    }

}

/********************************************************************************
 *                                                                              *
 *  TASK:           birinci led                                                 *
 *                                                                              *
 *------------------------------------------------------------------------------*
 *
 *  description:    birinci led yar?m saniyede yan?p sönsü
 *
 ********************************************************************************/

void birinci_led (void)
{
    for (;;)
    {
        LATCbits.LATC0^=1; //tersle
        OS_Delay(500 ms);
    }
}

/********************************************************************************
 *                                                                              *
 *  TASK:           ikinci led                                                  *
 *                                                                              *
 *------------------------------------------------------------------------------*
 *
 *  description:    ikinci led bir saniyede yan?p sönsün
 *
 ********************************************************************************/
void ikinci_led (void)
{
    for (;;)
    {
        LATCbits.LATC3^=1; //tersle
        OS_Delay(1000 ms);
    }
}

/********************************************************************************
 *                                                                              *
 *  TASK:           ucuncu led                                                  *
 *                                                                              *
 *------------------------------------------------------------------------------*
 *
 *  description:    ucuncu led iki saniyede yan?p sönsün
 *
 ********************************************************************************/
void ucuncu_led (void)
{
    for (;;)
    {
        LATCbits.LATC6^=1; //tersle
        OS_Delay(2000 ms);
    }
}

//******************************************************************************
//  THE END
//******************************************************************************

projemiz ile aynı klasörde olan OSAcfg.h dosyamız:

////////////////////////////////////////////////////////////////////////////////
//
// This file was generated by OSAcfg_Tool utility.
// Do not modify it to prevent data loss on next editing.
//
// PROJECT NAME: Running lights
// PLATFORM: HT-PICC 14-bit
//
////////////////////////////////////////////////////////////////////////////////

#ifndef _OSACFG_H
#define _OSACFG_H

#define OS_TASKS               3
#define OS_DISABLE_PRIORITY
#define OS_ENABLE_TTIMERS

#endif

 

Ancak bunların dışında bir de “osa” adlı klasör eklememiz gerekiyor. Bu klasör içindeki dosyalar OSA işletim sisteminin kütüphane dosyalarıdır. Bu klasörü eklemek için derleyici ayarlarınızdan yeni bir kütüphane yolu seçmeniz gerekecek. Bu işlemi mplab ide’sinde yapmak için:

 

daha sonra:

Yukarıdaki resimde dikkat etmeniz gereken, osa klasörünün projenizin bir üst klasöründe olması gerektiğidir.

MPLABX idesi için ise aşağıdaki yolu izleyiniz:

Aşağıdaki resimde 5 nolu çemberde görüldüğü gibi “relative” yi seçmenizi kesinlikle öneririm. Relative türündeki adresler bağıl adreslerdir. Projeyi başka bir yere taşıdığınızda(osa klasörü ile birlikte) adres güncellemeniz gerekmeyecektir. Relative türünde adresler “../osa” gibi bir üst klasör de olsun şeklinde verilebilir. Ancak absolute türündeki adresler kesin adreslerdir. Mesela “c://osa” gibi bir adres kesin adrestir c sürücüsündeki osa klasörünü başka bir yere taşıdığınızda projeyi derleyemezsiniz.

 

Yaptığımız örnek sadece OSA yı tanıtmak içindi, üzerinde durulursa çok güzel uygulamalar yapılabilir. Osa sadece pic mikro denetleyiciler için değil ATMEL, ARM gibi farklı MCU’lar içinde kullanılabilir. Ayrıca bahsettiğim osa klasörünü bu adresten de indirebilirsiniz: http://www.pic24.ru/lib/exe/fetch.php/osa/history/osa_110306.zip Web sitelerinde bir çok example projesi bulunuyor.

OSA RTOS’un web sitesi: http://www.pic24.ru/doku.php/en/osa/ref/intro

Projenin MPLAB ve MPLABX versiyonlarının yanında simülasyon dosyaları ve osa kütüphane dosyalarıda bulunmaktadır. İndirmek için tıklayınız: http://GokhanBeken.com/dosyalar/osa_rtos.rar

Mustafa Gökhan BEKEN

12.12.2013

4 thoughts on “OSA RTOS (PIC’ler için işletim sistemi)(C18 için bir çalışma)

  1. selamın aleyküm
    gökhan hocam mplab x ide için, OSA işletim sisteminin kütüphane dosyalarını nasıl ekleyeceğiz? Ben pic24 sitesindeki 3leds projesini mplab x xc8 derleyemedim bi türlü. OSA.h “No such file or directory” hatası veriyor. osa.h dosyasını C:\Program Files\Microchip\xc8\v1.21\include içerisine atıyorum bu sefer başka dosya eksik diyor.

    ilginiz için teşekkür ederim…

  2. dediklerinizi aynen yaptım ama
    ../lights_mcc18.c:28: error: (141) can’t open include file “osa.h”: No such file or directory

    hatası veriyor nedense

Bir Cevap Yazın