Neden Bilmiyorum ama içimden bir ses "bukadar kolay olamaz" diyor.
CooCox ile çalışıyorum. CoOS adında bir RTOS var./**
*****************************************************************************
* @title main.c
* @author slachist@gmail.com
* @date 31 Oct 2012
* @brief
*******************************************************************************
*/
////// The above comment is automatically generated by CoIDE ///////////////////
#include "stm32f10x.h"
#include "stm32f10x_gpio.h"
#include "stm32f10x_rcc.h"
#include <CoOs.h>
#define STACK_SIZE_DEFAULT 512
OS_STK task1_stk[STACK_SIZE_DEFAULT];
OS_STK task2_stk[STACK_SIZE_DEFAULT];
void initializeBoard(){
GPIO_InitTypeDef GPIO_InitStructure_Led;
GPIO_InitTypeDef GPIO_InitStructure_Button;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);//for LEds
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//for buttons
GPIO_InitStructure_Led.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9;
GPIO_InitStructure_Led.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure_Led.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure_Button.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure_Button.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_InitStructure_Button.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOC,&GPIO_InitStructure_Led);
GPIO_Init(GPIOA,&GPIO_InitStructure_Button);
}
void task1 (void* pdata){
while(1){
GPIO_WriteBit(GPIOC,GPIO_Pin_8,Bit_SET);
CoTickDelay (10);
GPIO_WriteBit(GPIOC,GPIO_Pin_8,Bit_RESET);
CoTickDelay (10);
}
}
void task2 (void* pdata){
int i;
while(1){
i = GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0);
GPIO_WriteBit(GPIOC,GPIO_Pin_9,i);
}
}
int main(void)
{
initializeBoard();
CoInitOS();
CoCreateTask(task1,0,0,&task1_stk[STACK_SIZE_DEFAULT-1],STACK_SIZE_DEFAULT);
CoCreateTask(task2,0,1,&task2_stk[STACK_SIZE_DEFAULT-1],STACK_SIZE_DEFAULT);
CoStartOS();
while(1);
}
bumudur yani? iki adet task tanımlıyor ve bunları main blogunun içerisinde oluşturup çalıştırıyor mu ?
Evet hocam pek zor değil ben de bir RTX-RTOS öğreneyim dedim.Sizin tepkiyi vermiştim.
Hocam Anladığımı Anlatayım.
void task1 (void* pdata){
while(1){
GPIO_WriteBit(GPIOC,GPIO_Pin_8,Bit_SET);
CoTickDelay (10);
GPIO_WriteBit(GPIOC,GPIO_Pin_8,Bit_RESET);
CoTickDelay (10);
}
}
biz bu blogu konvansiyonel olarak yazsaydık. bu blokton while dan dolayı hiç çıkamayacaktı.
RTOS dan dolayı kendisine belirten task zamanında çalışıp durumları kaydedip diğer task a geçiyor. Diğer task ta işini bitirdiğinde burada kaldığı yerden devam ediyor. (bir nevi her task interrupt rutini gibi çalışıyor.)
MU ?
mesaj birleştirme:: 18 Kasım 2012, 21:13:09
@yamak
Hocam Gözümüzde mi büyütmüşüz bu olayı. (Yoksa Hazır olmasından mı :) bukadar kolay geldi bize. RTOS yazılmış ben taskları ayarlıyorum.)
Alıntı YapHocam Gözümüzde mi büyütmüşüz bu olayı. (Yoksa Hazır olmasından mı bukadar kolay geldi bize. RTOS yazılmış ben taskları ayarlıyorum.)
Hocam galiba biraz büyütmüşüz. :)
Alıntı YapHocam Anladığımı Anlatayım.
biz bu blogu konvansiyonel olarak yazsaydık. bu blokton while dan dolayı hiç çıkamayacaktı.
RTOS dan dolayı kendisine belirten task zamanında çalışıp durumları kaydedip diğer task a geçiyor. Diğer task ta işini bitirdiğinde burada kaldığı yerden devam ediyor. (bir nevi her task interrupt rutini gibi çalışıyor.)
MU ?
Hocam bi de senkronizasyon olayları var onlara da bi bakın isterseniz bakmamışssanız.Onları öğrenince daha zevkli oluyo.Mesela bi task başka bi task event gönderebiliyo.Mesela ilk olarak A task ının çalıştırıyonuz sonra A B ye event gönderiyo sonra B çalışıyo.B de C ye gönderiyo vs. Bi de mutex muhabbeti var.
peki hocam super loop yapmaktansa neden round robin yapayım?
Hazır RTOS konusu açılmışken, uzun zamandır sormak istediğim bir soru var.
Örneğin
a,b,c,d,...n olan tasklarım var.
bir tane de dma taskım var.
bir DMA görev listem var.
a,b,c,d,... he biri bu listeye hedef , kaynak adresleri, uzunlık vs.. içeren bilgiyi ekledi. Bu görevlerin ne kadar süreceği belirsiz. Bu listeye veriyi ekleyince a,b,c.. tasklarının görevi şimdilik bitti.
dma taskı baktı ki listede 'a' taskının transfer isteği var. hemen dma donanımı ayrını yaptı gönder kardeşim dedi ve geriye çekildi.
DMA donanımı işini bitirince kesme geldi , dma taskı tekrar göreve başladı.
DMA taskı bu kesmeyi alınca, hemen listeye baktı sırada b taskının görevi var. b taskının görevi için DMA donanımını kurduktan sonra , az önce biten görevin kime ait olduğuna baktı. a taskınınmış bu biten görev dedi ve bir şekilde a taskını tekrar göreve çağırdı. a taskı da KALDIĞI YERDEN devam etti. Bu iş listedeki tüm görevler bitene kadar devam etti. Listeye yeni göre eklenince tekrar başladı.....
Özet olarak aslında aradığım şey şu: Bir taskın işi belirli bir süreliğine yoksa ve biz bu süreyi bilmiyorsak, kesme kaynağından gelen bir bilgi ile bu taskın aldığı yerden göreve devam etmesini sağlayabilir miyiz?
Eğer olursa, bunun için araştırılması kgereken konu , anahtar kelime nedir?
- mutex
- semaphore
- message passing(queues)
- event loop(event handling)
Kullanacaginiz RTOs'un uygun mekanizmalarina bakmaniz lazim. Eger performans/response time/latency gereksinimleriniz cok kati degilse, yani "Hard Real-time" bir system ile ugrasmiyorsaniz, POSIX compliant bir API sizin ihtiyacinizi gorebilir ve portable bir program yazmanizi saglar..
Hiç hard beklentilerim yok. Görev kaçırmasın yeter. Zamanlama kritik tek görevim haberleşme, o da 1 milisaniye gecikse bir şey olmaz. Olursa da onu farklı dma kanalları ve kesmelerle hallederim.
Üzerinde çalıştığım projeni birmesi gereken süre 2 ay kadar. Sizce bu projeye RTOS ile başlarsam en fazla 1 aylık bir gecikmeyle tamamlayabilir miyim? Yoksa bu projeye hiç başlama , bildiğin gibi yap. Biraz piştikten sonra gir bu işlere mi dersiniz?
Benim nacizane gorusum, bilinen bir RTOS ile baslarsaniz, 1 ayda biter, kendiniz bir scheduler vb yaparsaniz, 2 ayda bile bitmeyebilir, yada bilhassa projenin sonuna dogru sizi ciddi olarak rahatsiz edecek sekilde ugrastirir.
Bende bir soru sormak istiyorum. RTOS la ilgili forumdaki konuları okudum ama halen kafam basmıyor.
Elimde gyro,accelerometer,magnetometer,barometer ve gps var ayrıca dışarıdan 4 farklı pwm geliyor işlemcide okunuyor 4 farklı motor sürülüyor pid işleniyor adc ile voltaj, akım vs okuyorum şimdi ben bunları
while(1){
fonksiyon1();
fonksiyon2();
fonksiyonn();
}
olarak gelişi güzel işletiyorum. Eğerki bir timer(system tick timer olsun) kurup bunları zamanlara ayırıp çalıştırırsam
while(1){
if(fonk1zamani) fonksiyon1();
if(fonk2zamani) fonksiyon2();
if(fonknzamani) fonksiyonn();
}
cooperative çalışma oluyor mu? Oluyorsa bunun while(1){ fonksiyonlar() } pek farkı olmuyor sonuçta alttaki fonksiyon her durumda üsttekinin bitmesini bekleyecek neden ozaman ortaya yeni bi terim attıldı ?
Hadi bunu geçtik preemptive çalışalım dedik timer0 ı 1ms kurduk her 1 ms kesmesi geldiğinde
void Timer0_IRQHandler(){
zaman++;
if(fonk1zamani) fonksiyon1();
if(fonk2zamani) fonksiyon2();
if(fonknzamani) fonksiyonn();
}
aralarada yine iç içe kesmeler(i2c capture) karışacak ve bazı fonksiyonlar için yeri geldi 1ms yetmedi program epey bi dallandı diyelim stack şişmez mi? bu kritik zamanlamayı nasıl ayarlamak lazım?
yoksa ben herşeyi yanlış mı anlamışım ?
Alıntı Yapyoksa ben herşeyi yanlış mı anlamışım ?
Evet.
harika :) ozaman baştan tekrar okuyayım doğru olsaydı işin içinden çıkamayacaktım
Nöbette aklıma geldi,
işlem sırası geliyor, RTOS tarafından belirtilen sürede Task işletiliyor ve sıradaki Task a geçiyor. Peki Tasklardan Birinde "Zamanlama" yani Timer işlemi varsa ve belli bir sürede bir bu Timer dan dolayı Kesmeye girmesi gerekirse ne olur ?
Timer interrupt rutinini sen yazmıyormusun?
evet ben yazıyorum
Hocam RTX_RTOS da "run in privileged mode" diye bi olay var eğer bu aktifse interrupt oluştuğunda interrupt rutinine girer. Eğer bu mode aktif değilse interruptlar çalışmıyo.
Buradan devam Edeyim.
Anladım Benim gibi BAsit düzeyde Bu işi Öğrenmek isteyen biri için RTOS+Interrupt un Olmadığını anladım. Terimler üzerinden gitmeyi düşünüyorum
Mutex nedir ?
Semaphore Nedir ?
Bunlara neden nezaman ihtiyaç duyarım
sayin @gerbay yine mutex semaphore cart curt etmissin! ;) context switch, task/thread, lock filan gibi turkce olmayan kelimeler kullanarak bize havami atiyorsun! :P
Hem ben delay_us icin kucuk bir for loop yaptim, mis gibi calisiyor,
bide interruptda cok zaman harcamamak lazim filan gibi garip laflar etmissin. Ben suru programda ISR icinde while bloklari, printf satirlari gordum. Ne yani simdi bunlar yanlis da senmi dogrusunu biliyorsun? ::)
Bence senin RTOS kuyruk acin var, daha once RTOS kullandinmi bakalim yoksa bir ebook buldunda oradanmi okuyup yaziyorsun?
Qing Li'nin Real-Time Concepts for Embedded Systems kitabi bizdede var, naaber?
dikkat et foyan ortaya cikabilir!!! ;D
Alıntı yapılan: gerbay - 19 Şubat 2013, 13:10:43
yine radara girdim galiba ama Qing Li nin kitabını Caroline Yao ile birlikte yazdığını belirtmek lazım..
Son gunlerde ulkemizdeki muhafazakar ruzgardan dolayi artik referans verirken kadin yazar adlarini vermiyorum :P, (eger cok tepki gelirde tt olursam, en az 3 mesaj geriden yaziyorum. Kadinla erkek bir olurmu yahu... Otursun evinde cocuk baksin, kocasina bi tas sicak corba yapsin, camasir bulasik utu bir suru ev isi var, niye kitap yaziyorlar ki değilmi ama! :D
Simdi moderatorlerden sopa yiyecem ama, canim sikkin onun icin keyfim yerinde ! (nasil oluyorsa! ;)) Sayin moderatorler valla ciddiye alinacak bir sey degil, munferit bir sakaci alarmi! :)
Peki Usart tan bilgi geldiğinde "interrupt" da kullanamıyorken nereden bileceğim, datanın geldiğini ?
Alıntı yapılan: muhittin_kaplan - 19 Şubat 2013, 15:08:51
Peki Usart tan bilgi geldiğinde "interrupt" da kullanamıyorken nereden bileceğim, datanın geldiğini ?
af buyurun ama interrupt niye kullanamiyorsunuz?
pri.. bir şekilde çalışmayınca bu RTOS int kapalı oluyormuş ya hocam.
mesaj birleştirme:: 19 Şubat 2013, 15:18:53
Alıntı YapHocam RTX_RTOS da "run in privileged mode" diye bi olay var eğer bu aktifse interrupt oluştuğunda interrupt rutinine girer. Eğer bu mode aktif değilse interruptlar çalışmıyo.
premptive olmasinin size ne zarari var hocam. Premptive fixed priority scheduling kullaninki isler sizin icin daha kolay olsun.
Ama premptive olmak interruptlar kapali demek degil.
her serial data geldiginde (yada gittginde yada error oldugunda) ISR bilgiyi alir ve bir mailbox/queue/shared datat vb arayiciligi ilede taska bildirebilir. Round-Robin yada non-premptive scheduling kullanirsaniz bu sekilde halledebilirsiniz.
Kolayını öğreneyim hocam önce.
Yeri Gelmişken Çalışma Çeşitleri ve Aralarındaki Farklar neler ?
Alıntı yapılan: muhittin_kaplan - 19 Şubat 2013, 15:22:57
Yeri Gelmişken Çalışma Çeşitleri ve Aralarındaki Farklar neler ?
Hocam bu Temelin bilgisayara "Ne var? Ne Yok?" diye sormasina benzedi! :)
Bu sorunun cevabi cok kapsamli olur. Size ozet olarak yapmak vermek icin 2-3 gun calismak gerekebilir. Belki yuzyuze sorulu/cevapli yada yazili referansdan bakarak ogrenmek en dogrusu.
Yinede wikipediadan bakabilirsiniz. http://en.wikipedia.org/wiki/Real-time_operating_system#Algorithms (http://en.wikipedia.org/wiki/Real-time_operating_system#Algorithms)
========================================
Advantages of Preemptive Scheduling
The main advantage of preemptive scheduling is real-time response on the task level. The task response time - i.e., the time required to activate a task waiting for an interrupt - largely depends only on the interrupt latency (the time span during which no other interrupts can be accepted). In cooperative scheduling, the task response time is the longest time span that can elapse between two calls to the kernel. Unfortunately, an upper limit for this time span cannot be defined in many cases. It is the responsibility of the programmer to ensure that the time spans between calls to the kernel or the scheduler are sufficiently small.
Advantages of Cooperative Scheduling
With cooperative scheduling and the single-processor kernel, substantially fewer reentrance problems are encountered than in preemptive scheduling, because tasks cannot be interrupted arbitrarily by other tasks, but only at positions permitted by the programmer (i.e., in kernel calls). This advantages does not apply to the multiprocessor kernel.
It should be noted that even though real-time response is impeded on the task level, it is fully preserved on the interrupt handler level. Interrupt handlers can continue to use semaphores and mailboxes in cooperative scheduling. Therefore, interrupt-driven modules like RTCom can run independently of the scheduling algorithm currently active. Also, these modules' performance is identical in both cases.
While RTKernel-32's Idle Task is running (or a task with a similar structure, e.g., the CPU Monitor Counter task), tasks' response times to interrupts are practically identical, with or without preemptive scheduling.
For programs that don't require a response time on the order of micro- or milliseconds at the task level, cooperative scheduling is recommended.
Hocam Döküman Toplamaya Başladım. Okuyorum.
Peki Her Task geçişinin 10ms olduğunu düşünürsek,
TaskA işlemini 10ms bitiremezse Başta Tanımladığımız Stack a mı yazıyor "Kaldığı yerdeki" Değerleri ? (Ki Tekrar TaskA ya geldiğinde Değerleri Yükleyerek kaldığı yerden devam etsin)
Böylemi Oluyor ?
Bazı terimleri Bilmediğimden Herhalde Biraz Havada Kalıyor.
Stacktan Kastım
OS_STK uart_print_Stk[TASK_STK_SIZE];
gibi tanımlamalar görüyorum. uart taskı için ayrılmış geçici depolama alanı olarak anlıyorum. ve mantığım "he bu kullanılsa kullanılsa buradaki değişkenleri vs yi yada kaldıkları yer için kullanılır" diyor.
peki tasklar neden değer döndürmüyor ve parametre almıyor ? ben bir tasktan başka bir task a bilgi gönderemeyecekmiyim ?
örnek olarak Uarttan okunan bir bilginin (task_usart), pwm değerini etkilediğini düşünürsem (task_pwm) ne yapmam gerek ?
CoOs'da message queue veya mailbox kullanabilirsiniz
Bu Dediklerinizi Öğrenebilirsem Kullanacağım Hocam.