Haberler:

Eposta uyarılarını yanıtlamayınız ( ! ) https://bit.ly/2J7yi0d

Ana Menü

ARM vs PIC

Başlatan mr.engineer, 15 Mayıs 2021, 20:45:07

mr.engineer

Merhaba,

ARM işlemcilerinde çevre birimlerin kesmelerini kullanırken öncelik (priority) ayarlaması yapabiliyoruz. 0,1,2...7 ye kadar veya daha fazla öncelik ataması yapılabiliyor. Her kesme için farklı bir ISR fonksiyonu kullanıyoruz.

PIC'de sadece "high priority" ve "low priority" var. Yani vector table da sadece ikisi var. Her çevre birim için ayrı bir kesme yok. (Tüm PIC'ler böyle mi bilmiyorum) En fazla iki kesme fonksiyonu oluşturup if-else kullanarak öncelik ayarlaması yapıyoruz.

ARM'a göre bunun avantajı veya dezavantajı nedir?

Bir de anlamadığım madem sadece if else ile öncelik ayarlaması yapacaksın neden "high priority" ve "low priority" diye iki ayrım yapıyorsun. Tek bir kesme fonksiyonunun içine tüm kesmeleri if-else ile yapalım olsun bitsin. Bunun sebebi nedir acaba?

RaMu

Hangi Pic hangi Arm.
Pic vs Arm demekle
Fotoğraf vs Kol demenin bir farkı yok,
ikisi bambaşka şeyler.
Sormak istediğini anlıyorum ama kavramlar oturmamış.

Tarihi eser bir Pic ile Cortex Arm işlemci kullanan yeni seri bir mcu yu kıyaslarsan bu iş olmaz.
Sorularınıza hızlı cevap alın: http://www.picproje.org/index.php/topic,57135.0.html

yas

#2
PIC serilerinin hangilerinde var bilmiyorum ama PIC33CH serilerinde 8 adet kesme seviyesi mevcut. ISR fonksiyonu birazda derleyiciyle alakalı diye düşünüyorum. Bende bu aralar PIC33CH serilerine gözümü diktim numune temin edip biraz kurcalamak istiyorum. Birçok eski pic mcu lar da sizin de söylediğiniz gibi kesme içerisinde bayrakları if veya select ile swicth ederek yönettik bu zamana kadar hiçbir şeyden geri kalmadı diye düşünüyorum. Konuyu takipteyim.

Edit: Resim ilave.



https://www.hizliresim.com/ivrgiap

mr.engineer

Alıntı yapılan: RaMu - 15 Mayıs 2021, 20:58:14Hangi Pic hangi Arm.
Pic vs Arm demekle
Fotoğraf vs Kol demenin bir farkı yok,
ikisi bambaşka şeyler.
Sormak istediğini anlıyorum ama kavramlar oturmamış.

Tarihi eser bir Pic ile Cortex Arm işlemci kullanan yeni seri bir mcu yu kıyaslarsan bu iş olmaz.


PIC18F24Q10. ARM için gördüğüm cortex-M0/M3 işlemcilerinin hepsi böyle.
Kullandığım PIC ne kadar eski bilmiyorum. Düşük seviye bir MCU.

PIC'de kesmelerin bu şekilde olması eski olmasıyla mı ilgili? Ben böyle tercih etmişler diye düşünmüştüm:)

z

#4
PIC işlemciler, ortalıkta yetenekli pek çok işlemci varken çok geç gelen bir işlemci. Ancak PIC serisi içinde flash barındırdığı için öne çıktı. Zira rakipleri eprom yada rom kullanırken çok azı CPU'ya entegre edilmiş ROM içeriyordu. Çipe entegre rom, ya oprom ya mask rom ya da epromdu. Haliyle flash teknoloji büyük fark yarattı.

Microchip, PIC ailesinde Int konusundaki yeteneklerine fazla önem verilmedi. Oysa zamanın rakip işlemcilerinde en azından vektorler fazlaydı.

Vektörlerin çok olması if else karşılaştırmaları ile yapılan zaman kaybını önler. Priority, Nested Int yapısı varsa anlam kazanır. Yani işlemci düşük seviyeli bir int geldiğinde int rutinine dallanıp işlemleri yaptığı sırada yüksek öncelikli iint gelirse o anki int rutinini yarıda kesip yüksek öncelikli int rutinine dallanırsa priority anlam kazanır.

Aksi halde aynı anda gelecek iki ayrı öncelikteki intdan yüksek önceliklinin hizmete alınması çok da avantaj sağlamaz.

PIC işlemcideki priority durumunu bilmiyorum. Eğer kesme kesmeyi kesmiyorsa dediğim gibi fazla bir önemi yok.

Cortex işlemcilerde hemen her in'ın kendine ait vektörü olduğu için int rutinine hızlıca geçiş mümkün. Üstelik öncelik sıralaması nedeniyle int diğer int rutininin akışı kesip önceliği ele almaktadır.

Dolayısı ile Int konusunda Cortex işlemciler ön plana çıkar.
Bana e^st de diyebilirsiniz.   www.cncdesigner.com

Okan AKÇA

Hatırladığım kadarıyla Aynı anda iki kesme gelirse öncelikli kesmeye gidiliyor. Ancak kesme içinden diğer öncelikli kesmeye gitme durumu olmaması gerekli.

RaMu

Zamanında çok yaygın kullanılan çok örneği bulunan 16F877 16F84 gibi Pic lerde tüm kesmeler 0x0004 program memory adresine dallanır.

Vectored Interrupt Controller
VIC modülü olan veya diğer manada
Interrupt Vector Table IVT olan Piclerde ise
kesmelerin ayrı ayrı dallanma adresleri bulunur.
Kesme hangi modülden geldi diye programcının program yazarak karar vermesi gerekmez.

Burada iki kesmenin aynı anda gelmesi veya
bir kesme işlenirken başka bir kesmenin gelmesi durumu ise apayrı bir konu ve
onun içinde Interrupt Priority var,
bu öncelik işi Pic i miki farketmez diğer mcu lar içinde aynı derttir.

Priority nin yapabileceği adından belli
aynı anda iki kesme birden gelirse öncelikli kesmeyi önce işlemek,
+
bir kesme işlenirken daha öncelikli bir kesmede gelirse
çıkıp öncelikli olanı işlemek.

https://microchipdeveloper.com/8bit:18finterrupts

https://microchipdeveloper.com/8bit:vectored-interrupts

Bayağıdır Pic e bakmadım, yanlış hatırladığım şeyler olabilir.
Sorularınıza hızlı cevap alın: http://www.picproje.org/index.php/topic,57135.0.html

Tagli

PIC'lerle uğraşmayalı epey oldu ama hatırladığım kadarıyla;
1) PIC16 -> Tek vektör
2) PIC18 -> Düşük ve yüksek öncelikli olmak üzere 2 vektör. Bir kesme istenilen vektöre atanabiliyor
3) dsPIC ve PIC24 (16 bit'likler) -> Her kesmeye ayrı vektör (paylaşılanlar olabilir)

@z açıklamış zaten. Vektörler paylaşıldığı zaman, aynı vektörü paylaşan kesmeler birbirini kesemez. Ayrıca if-else bloklarını taramanın, dal sayısıyla orantılı bir maliyeti olacaktır.

Cortex M'lerde sub-priority diye bir şey de var, istenirse etkinleştiriliyor. Bu durumda çalışma mantığı vektör paylaşımında if-else kullanmaya benziyor. Aynı önceliğe (ancak farklı alt-önceliğe) sahip kesmeler birbirini kesmiyorlar, ancak eğer aynı anda sıra bekliyorlarsa alt-önceliklerine göre işleme alınıyorlar.
Gökçe Tağlıoğlu

mr.engineer

#8
void __interrupt(high_priority) MyHighPriorityIsr(void)
{
   
    if(IOCIE && IOCIF)   // INTERRUPT 1
    {
        if(IOCBF1)
        {
          IOCBF1 = 0;
        }
        IOC_CallBack();
    }
    else if(PIE4bits.TMR1IE && TMR1IF)      // INTERRUPT 2
    {
        PIR4bits.TMR1IF = 0;
        SetAutoReload_TIM1(timer1ReloadVal);
        TMR1_CallBack();
    }
    else if(PIE0bits.TMR0IE && PIR0bits.TMR0IF )   // INTERRUPT 3
    {
        PIR0bits.TMR0IF = 0;
        SetAutoReload_TIM0(timer0ReloadVal);
        TMR0_CallBack();
    }
}

Yukarıda 3 interrupt var. Kod istediğim gibi çalışıyor. İf ile başlayan en yüksek önceliğe sahip. Yüksek öncelikli int geldiğinde daima kesilecek.
@Tagli aynı vektörü paylaşan kesmeler burada birbirini kesmiyor mu? Kesebiliyor.
@z hocamın dediği şekilde yüksek öncelikli kesmeye sahip olan düşük olanı burada kesiyor.

Acaba kastettiğiniz nested int şu mu; önceliği yüksek kesme rutini çalışırken, düşük öncelikli olan gelirse sıraya alınması lazım. Diğer işlemcilerde böyle oluyordu. Burada sıraya alma olayı (pending interrupt) olmuyor mu? Yani yüksek önceliklinin işi bitince, düşük önceliğe sahip olan çalışacak.

Bir de paylaştığım kodda her kesme geldiğinde flagler 0 yapılıyor. Şimdi düşününce; bu kodda düşük öncelikli kesmeler, yüksek öncelikli kesmeleri kesebiliyor. Burada flag yanlış yerde sıfırlanmış galiba.

 


Tagli

Alıntı yapılan: mr.engineer - 15 Mayıs 2021, 23:30:17aynı vektörü paylaşan kesmeler burada birbirini kesmiyor mu? Kesebiliyor.
Hayır, kesemiyorlar. Yüksek öncelikli bir kesme işlenirken başka bir yüksek öncelikli kesme gelirse sırasını beklemek zorunda. Zaten öbür türlü olsa idi aynı önceliği paylaşıyor olmazlardı. If-else sıralaması, sadece sırada bekleyen aynı önceliğe sahip kesmelerden hangisinin daha önce işleneceğini ifade eder. Ancak bir kesme işlenmeye başladıktan sonra o iş bitene kadar aynı vektörü paylaşan bir başka kesme işleme alınamaz, sırada bekler. Önceki mesajımda dediğim gibi, Cortex M terimleriyle konuşursak bu durum sub-priority'ye denk gelir.

PIC18 için konuşursak gizli bir kesme kuyruğu yok. Bir kesme işlenmeye başlayınca, yani vektörün içine girilince zaten o vektöre ait global kesme izni iptal oluyor vektörden çıkana kadar. PIC16'larda bunun adı INTCON.GIE idi. PIC18'lerde 2 vektörün kendi ayrı izin biti var, isimlerini unuttum. Bir vektöre bağlı kesme sinyallerinin OR'landığını düşün. O yüzden bir kuyruk yok. Hangisinin önce çalışacağını senin if-else sıralaman belirliyor. Sırada bekleyen (kendi biti 1 olan) tek bir sinyal bile varsa, vektörden çıkar çıkmaz tekrar aynı vektöre giriş olur.

Kesme içinde önce modül bayrağı indirildikten sonra INTCON.GIE daha çıkmadan 1 yapılarak yeni kesmelere izin verilebilir teorik olarak. O zaman aynı vektördeki kesmeler de birbirini kesebilir. Ama PIC'lerin donanımları ve bildiğim kadarıyla derleyicileri böyle bir kullanım için uygun değil. İç içe kesme olması register yedeklemelerini çok zorlaştırır. Bazı modellerde buna yönelik donanım desteği var shadow register denen bu yedekleme register'larının derinliği sadece 1. Yani iç içe yedeklemeyi desteklemiyorlar. Ayrıca PIC'lerde, Cortex M'lerin aksine dinamik bir stack ve donanımsal PUSH-POP desteği de yok. Sadece fonksiyon dönüşleri için program counter yedeğini alan çok sınırlı bir donanımsal stack var (eski modellerde derinliği 8 falandı, sonra biraz daha arttırdılar galiba).

dsPIC'leri ve PIC24'leri hatırlamıyorum, 8 bit'lik modeller için konuştum.

Bu arada ayrı vektörlere sahip olmanın getirdiği önemli bir avantaj daha var: Yazılımı daha modüler yazmaya olanak veriyor. Atıyorum, Modbus'a yönelik bir kod yazıyorsam ve bunu modbus.c dosyasına koyuyorsam, USART kesme vektörünü de bu dosya içinde tanımlamak isterim. PIC16 & PIC18'de bu mümkün değil. Elbette if-else bloğu içinde TMR0_CallBack(); gibi çağrılar yapabilirsin ama yine de aynı tadı vermiyor bence.

Ben Cortex M'lerde işi biraz daha abartıyorum: Normalde flash'ta olan vektör tablosunu RAM'e taşıyorum ve işlemci çalışırken buradaki kesme fonksiyonlarını güncelliyorum. Bu özellik, yeniden kullanılabilir ve genelleştirilebilir kod yazmayı epey kolaylaştırıyor. Kesme fonksiyonlarına istenildiği gibi isim verilebiliyor, hatta C++ function tempate'leri kullanılarak aynı fonksiyonun kopyaları farklı vektörlere bağlanabiliyor. Mesela benzer iş yapan 3 timer modülü için 3 kesme fonksiyonu oluyor ama tek bir kod var.
Gökçe Tağlıoğlu

yas

8 bitlik pic için söylüyorum. Derleyici (yada asm ile kodlanıyorsa) kesme rutinine girildiğinde GIE kapatılmazsa rutinden çıkmadan bir kesme daha gelirse tekrar kesme rutinin başına atlıyor. Bu kesmelerin bir birini kesebilmesi anlamına da gelse iyi yönetilmediği zaman @Tagli nin belirtiği gibi registerları geri yüklerken kayıplar olabiliyor ve kesmelerden sonra program doğru yere dönemeyebiliyor. Bu nedenle kesme rutininde GIE kapatılmalı yada geri dönüş için registerlar doğru saklanmalı.

Tagli

Alıntı yapılan: yas - 16 Mayıs 2021, 00:19:47Bu nedenle kesme rutininde GIE kapatılmalı yada geri dönüş için registerlar doğru saklanmalı.
Normalde bunu işlemci kesme girişinde otomatik olarak yapıyor. Kesme dönüşünde de derleyici RETFIE (doğru hatırlıyorsam) komutu ile kesmeleri tekrar açıyor. Yani kesme kodu içinde GIE ile oynamaya gerek yok. Tabi elle açılırsa evet iç içe kesme alınabilir ama işler çok karışır.
Gökçe Tağlıoğlu

mr.engineer

#12
@Tagli teşekkürler, yanlış anladığım yeri anladım.

Bu GIE'yi sürekli 1 yaparak sıradaki kesmeleri almak pek aklıma yatmadı. İçerde if-else yapısı varken, önce if bloğundaki kesme çalışıyorsa ve sonra başka bir kesme gelmişse bunun sub-priority'si düşük( yani else if e ait) olacak ben bunun kesmesini istemem. Dediğiniz gibi karışık galiba o kısım:) Yani yazılımla çözülecek bir iş değil.

Her neyse benim anladığım bu iki vektörlü yapı biraz kötü olmuş. Yani bir vektörü paylaşan kesmelerin birbirini kesememesi zaman kaybına yol açıyor. Bu tür işlemcileri biraz olsun büyük projelerde veya kritik zamanlama gerektiren işlemlerde kullanmak zor olur.

RaMu

DMA modülünü kullandıktan sonra DMA sız mcu kullanmamak lazım diye düşünmeye başladım.
Şu anki fiyatları göz önüne almazsak ST32 lerin fiyat ve geliştirme ortamı rahatlığı varken Pic lere bakamıyorum bile
yoksa aynı özellikler Pic32 dede var.

Stm32 Dma modülü bak tavsiye ederim alışkanlık yapıyor şimdiden uyarayım.

@Tagli  hazır yazıyorken bende mi bir konu açsamda
Stm32 CCM Core Coupled Memory den bahsetse bize :)

Alıntı yapılan: Tagli - 16 Mayıs 2021, 00:05:22...
Ben Cortex M'lerde işi biraz daha abartıyorum: Normalde flash'ta olan vektör tablosunu RAM'e taşıyorum ve işlemci çalışırken buradaki kesme fonksiyonlarını güncelliyorum.
...
Sorularınıza hızlı cevap alın: http://www.picproje.org/index.php/topic,57135.0.html

z

#14
Alıntı yapılan: mr.engineer - 16 Mayıs 2021, 02:25:05@Tagli teşekkürler, yanlış anladığım yeri anladım.

Bu GIE'yi sürekli 1 yaparak sıradaki kesmeleri almak pek aklıma yatmadı. İçerde if-else yapısı varken, önce if bloğundaki kesme çalışıyorsa ve sonra başka bir kesme gelmişse bunun sub-priority'si düşük( yani else if e ait) olacak ben bunun kesmesini istemem. Dediğiniz gibi karışık galiba o kısım:) Yani yazılımla çözülecek bir iş değil.

Her neyse benim anladığım bu iki vektörlü yapı biraz kötü olmuş. Yani bir vektörü paylaşan kesmelerin birbirini kesememesi zaman kaybına yol açıyor. Bu tür işlemcileri biraz olsun büyük projelerde veya kritik zamanlama gerektiren işlemlerde kullanmak zor olur.

Yazilimla da yaparsin da int geldiginde int onceligini arastiracak rutin karar verinceye kadar zaten mevcut intin gereksinimi yazilimi coktan kosturur bitirirsin.
Bir de dusuk dongu sureli gercek zamanli coklu islemler icin PIC secilmez. Fakat hiz gerektirmeyen ve intlarin onceligini dikkate almayi gerektirmeyecek o kadar cok uygulama var ki o projeler icin PIC ailesi cok cok uygun.

Yoksa Cortex M0 ve M3 serisinin de eksikleri var ve M4 fakat daha pahali serilerinde cozum olarak geliyor.
Bana e^st de diyebilirsiniz.   www.cncdesigner.com