Değişkene> 1 ISR'den erişildiğinde, ancak ISR dışında paylaşılmadığında değişkenliğe gerek var mı?


9

Oluyor açıkça belgelenmiş global veri bir ISR ve ana program ile paylaşıldığında, veri ihtiyacı tanımlanmak zorunda olduğunu volatilegaranti bellek görünürlüğü için (ve sadece 1 bayt veri için yeterli; birşey daha büyük ihtiyaçları da teminat bölünmezlik için özel düzenlemeler) . Burada iyi kurallarımız var:

  • Yalnızca ISR dışında kullanılan değişkenler uçucu olmamalıdır.
  • Yalnızca bir ISR içinde kullanılan değişkenler uçucu olmamalıdır.
  • ISR'nin içinde ve dışında kullanılan değişkenler değişken olmalıdır.

Ancak volatiledeğişkene> 1 ISR'den erişilip ISR dışında paylaşılmadığında gereklidir? Örneğin, bir staticdeğişken kullanarak iç durumunu koruyan bir işlevim var:

void func() {
    static volatile long counter; // volatile or not?
    // Do stuff with counter etc.
}

Bu işlev iki şekilde çağrılır: pin kesmesinden ve TimerOne kütüphanesinden :

  1. attachInterrupt(0, func, CHANGE);
  2. Timer1.attachInterrupt(func);

Atomisite sorunu yoktur, çünkü bir ISR girildiğinde, kesmeler otomatik olarak devre dışı bırakılır , ancak bu volatiledaha çok bir derleyici sorusudur: önbelleğe alınmış olan ve olmayan.

Elbette üzgün olmaktan daha güvenli ...

Yanıtlar:


9

volatile yalnızca derleyicinin kod üreticisine değişkenin üretilen koddan başka bir şeyle değiştirilebileceğini bildirir, bu nedenle herhangi bir kopyasının doğru kaldığını varsaymamak gerekir.

ISR kodu, girişte bağlam olmadığı varsayımı altında yazılmalı / oluşturulmalı ve CPU'nun (ISR) kendi işlemi etrafında bağlamını korumalıdır. Bu nedenle, atomik olmayan işlemlerin bölünemezliğinde olduğu gibi, oynaklık bu durumda * kesintilerin yuvalanmasına izin verilip verilmeyeceğine bağlıdır . Yuvalamama garanti edilirse, paylaşılan değişken kendi yürütülmesi sırasında bu ISR dışında bir değerle değiştirilemez. ISR'niz bir gün kesintilerin yuvalanmasına izin verilen bir ortamda kullanılabiliyorsa, bu kısıtlama artık geçerli olmayacaktır.

* Bu durumda :
Burada yazılım tarafından korunan bir değişken olduğunu varsayıyorum. Bir donanım olayı tarafından güncellenebilen bir değişkenten bahsediyorsak, örneğin bir zamanlayıcı kaydı, tüm bahisler kapalıdır: değişken ne olursa olsun değişkendir.


Bu nedenle, Arduino'nun varsayılan "kesintileri iç içe geçmez" davranışını değiştirmediğim sürece volatile, oluşturulan koddan başka bir şey tarafından değiştirilmediğinden değişkenin olması gerekmez ; derleyici, ISR'nin doğrusal olarak yürütüldüğünü "kesebilir" ve kesmeler iç içe geçmediği sürece yapar. Mantıklı. Teşekkürler!
Joonas Pulakka
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.