Independent watchdog (IWDG)
STM32L051 işlemcisinde bulunan Independent watchdog
özelliğini inceleyeceğiz.
Bu yazımızda bir problemin oluşması durumunda veya zaman
aşımı uygulamaları için kullanılan bu özelliği inceleyeceğiz.
Yazılım hatasından kaynaklanan arızaları çözmek için
kullanılır.
- Zaman aşımı oluştuğunda sistem reset’i oluşturur.
- Ana clock sinyali bir hatadan dolayı dursa bile her zaman aktiftir.
- Bir kez aktif edilmiş ise kapatılamaz sadece tekrar yenilenmek zorundadır. Yani timeout sayacını sıfırlamak gerekir.
Uygulama avantajları:
- Ana uygulama dışında tamamen bağımsız bir işlemdir.
- Donanım veya yazılım ile başlatılabilir.
- Standby modunda veya stop modunda low-power olarak dondurabilir.
Yazılım hatasından kaynaklanan sorunları tespit etmek için ve
çözmek için kullanılır. Sayıcı zaman aşımı değerine ulaştığında bir reset
sırasını tetikler. Saat bağımsız bir 37 kHz düşük hızlı dahili RC osilatöre
(LSI RC) sahip olduğundan, ana clock başarısız olsa bile watchdog aktif kalır. Bir
kez aktif edildiğinde sadece bir reset ile pasif edilebilir.
Uygulamalar için en önemli yararlarından birisi, ana clock’dan
bağımsız çalışabilme yeteneğidir. Ayrıca, IWDG, isteğe bağlı baytları
kullanarak donanım veya yazılım aracılığıyla yapılandırılabilir. Stop mod
veya Standby süresince IWDG sayacı dondurulabilir.
IWDG ana özellikleri:
- 12-bit bağımsız çalışan downcounter
- Bağımsız RC osilatörden Saat sinyali (LSI)
- Koşullu Reset ( watchdog aktif ise)
- Downcounter değeri 0x000’a geldiğinde
- Downcounter sayacı window dışında tekrar yüklendiğinde ( window opsiyonu seçili ise)
IWDG 12-bit bağımsız çalışan bir downcounter sayacına sahiptir.
37-kHz olan dahili bir low-speed osilatörden saat sinyalini alır.
IWDG ne zaman aktif edilir ise, downcounter sayacı sıfır
gittiğinde veya downcounter window dışında tekrar yüklendiğinde (bu opsiyon
aktif ise) reset sinyali oluşturulur.
IWDG register’ları CORE voltajının bulunduğu alana
yerleştirilmiştir. Bu mimari kullanılarak IWDG özelliği Stop ve Standby
modlarında kullanılabilmektedir. LSI osilatör frekansı 8-bit prescaler ile
bölünerek kullanılmaktadır.
IWDG başlatıldığında 12-bit sayaç reset değeri olan
0xFFF’den aşağı doğru saymaya başlar. IWDG sayacını yenilemek için Anahtar
değer olarak 0xAAAA Key register içerisine yazılarak sayacın terkrar geri
yüklenmesi gerekmektedir. Yani bu anahtar girilmeden sayaç temizlenemez.
Yazılım içerisinde yanlışlıkla bu sayacın temizlenmesi imkânsızdır.
Downcounter sayaç değeri(0x000) olduğunda bir sistem reset
sinyali üretilir.
Window opsiyonu aktif edilmiş ise, sayaç window içerisinde yenilenmek
zorundadır. Window dışında yenilenir ise bir sistem reset sinyali oluşturulur
ve sistem resetlenir.
IWDG donanımı cihazın opsiyon byte’ları ile aktif edilir.
Aktif edildi ise, watchdog power on durumunda otomatik olarak başlatılır.
Herhangi bir reset’lenmeyi önlemek için Key register sayaç 0
değerine ulaşmadan önce veya window’da (bu opsiyon aktif ise) düzenli
aralıklarla yenilenmelidir. IWDG yazılımda başlatılması birkaç adımda
yapılandırılır.
- İlk adım watchdog’un başlatılması için Key register’a 0x0000 CCCC yazılır.
- Daha sonra IWDG register koruması 0x0000 5555 yazılarak kaldırılır.
- IWDG prescaler IWDG_PR register üzerinden ayarlanır.
- Watchdog sayacı IWDG_RLR reload register üzerinden başlangıç değeri ayarlanır.
Önceki kayıtlara eriştikten sonra kayıtların güncellendiğini
onaylamak için IWDG_SR bitinin sıfırlanmasını beklemek gereklidir.
- İki seçim mevcuttur. IWDG window opsiyonu aktif etmek veya pasif etmek.
- IWDG_WINR register içerisine window değeri yazılarak window opsiyon aktif edilir.
- Diğeri, Key register içerisine 0x0000 AAAA yazılarak window opsiyonu pasif edilir.
IWDG zaman tabanı LSI saatinden 37kHz'de beslenir. IWDG_PR
prescaler register LSI saat frekansını 4’den 256’ye kadar bölebilir. Watchdog
sayacı tekrar yükleme değeri 12-bit olarak IWDG_RLR register içerisine
yazılabilir.
IWDG zaman aşımını belirlemek için bir formül
kullanılabilir. IWDG zamanı seçilen watchdog sayıcısının geri yükleme değerinin
yanı sıra LSI periyoduna ve prescaler değerine bağlıdır. Parametre limitleri
göz önüne alındığında, IWDG zaman aşımı değeri :
37kHz / 4(prescaler) = 9,25ms *
4095(reload value) = 37,8 saniye
37kHz / 256(prescaler) = 144,5us
* 1(reload value) = 144,5 us
arasında olabilir.
IWDG çevrebirimi tarafından bir reset sinyali oluşturulduktan
sonra, RCC_CSR register içerisinde yer alan IWDGRSTF bayrağı işlemcinin hangi
sebepten reset’lendiğini anlamak için set edilir.
Mikro kontrolör Debug moda girdiğinde, IWDG sayacı DBG
modülündeki DBG_IWDG_STOP bit’inin değerine bağlı olarak normal çalışmaya devam
eder veya durur.
IWDG, beslemenin kapalı olduğu durum olan Shutdown modu
hariç tüm çalıştırma ve düşük güç modlarında etkin olabilir. Bununla birlikte,
Stop0, Stop1, Stop2 ve Bekleme modlarında, watchdog sayacı FLASH_OPTR register’ın
ilgili bitleri programlanarak dondurulabilir.
Şimdi bunu STM32CubeMx ve Atollic IDE kullanarak uygulayalım
ve sonuçlara bakalım.
Öncelikle CubeMx’de projemizi adım adım oluşturalım.
Resimde görüldüğü gibi “New Project” kısmına basalım.
Çıkan listeden kullanacağımız işlemciyi seçelim. Ben
STM32L051K8T6 kullanacağım için yukarıdaki resimde de görüldüğü üzere bu
işlemciyi seçip “OK” butonuna basıyoruz.
Projemiz için ana ekran yukarıdaki şekilde geldi.
Öncelikle Atollic programında debug yapabilmek için yukarıda
görüldüğüü gibi “Peripherals” sekmesinin altında yer alan “SYS” sekmesinin
altındaki “Debug Serial Wire” seçeneğini seçiyoruz. Bu seçimi yapmadan proje
oluşturduğumuzda Atollic programı debug yapmamıza izin vermeyecektir.
Daha
sonra “Peripherals” sekmesinin altında bulunan “IWDG” sekmesinden “Activated” kısmını işaretleyerek Independent
Watchdog özelliğini aktif hale getiriyoruz.
Daha sonra
“Clock Configuration” kısmına gelip HCLK değerini 32MHz olarak değiştirip Enter
tuşuna basıyoruz. Böylece sistem clock frekansımızı 32MHz olarak ayarlamış
oluyoruz.
Resimde de görüleceği üzere IWDG clock kaynağı 37kHz’dir. İncelemelerim
sonucunda her işlemci ailesinde bu değer farklılıklar göstermektedir.
Şimdi de LED’lerimizin bağlı olduğu pinleri ayarlayalım.
Kırmızı LED’imizi PB7 pinine , yeşil LED’imizi de PB6 pinine
bağlayalım. Pin üzerine gelerek sağ tuş ile açılan menüden “Enter User Label”
seçeneğini seçerek LED’lerin isimlerini tek tek girelim.
Daha sonra
Yukarıdaki resimde işaretlenmiş olan “Configuration”
sekmesinde bulunan “IWDG” butonuna tıklayarak IWDG menüsünü açınız.
Burada 3(üç) adet parametre bulunuyor. Bunlar;
- IWDG counter clock prescaler
- IWDG window value
- IWDG down-counter reload value
Yukarıdaki anlatılan formülü hatırlayalım:
İstenilen Zaman = (LSI RC Osilatör Frekansı / Prescaler)*
down-counter reload değeri
Biz presclaer değerini 32, ve down-counter reload değerini
865 verirsek,
İstenilen Zaman = (37 kHz / 32)*865 = 1000,15ms olarak
hesaplanır. Yani biz sistemin resetlenmemesi için yaklaşık 1 saniye içerisinde
down-counter reload değerini yeniden yüklememiz gerekecek.
Bu değerleri parametrelere girdikten sonra “OK” butonuna
basarak menüden çıkalım.
Şimdi proje ayarlarını yapacağız.
“Project”
menüsünden yukarda görüldüğü gibi “ Setting…” kısmına basarak proje ayarlarını
yapacağımız menüyü açalım.
Ben proje ismi olarak IWDG_DENEME ismini verdim. “Project
Location” kısmına programın nereye oluşturulmasını istiyor iseniz oranın yolunu
yazın. “Toolchain /IDE” kısmından Atollic IDE ile çalışacağımızdan dolayı “TrueSTUDIO”
seçeneğini seçiyoruz. “OK” butonuna basarak menüyü kapatıyoruz.
“Project” kısmından “Generate Code” kısmını seçerek
programın oluşturulmasını sağlıyoruz.
Karşımıza yukarıda resmi gösterilen onay menüsü gelecektir.
Eğer çalışma ortamınız Linux ise “Open Folder” butonuna basın. Çünkü Linux
sistemlerinde Atollic otomatik açılmıyor. Windows ise “Open Project” butonuna
basıyoruz. Atollic programı otomatik olarak oluşturulan programı açacaktır.
Atollic projeyi açtıktan sonra “Src” klasörü altında bulunan
“main.c” dosyasına çift tıklayarak açıyoruz.
Daha sonra programımızı derlemek için;
Yukarıdaki resimde gösterilen çekiç sembolüne basarak
derleme işlemini başlatıyoruz.
Resimde
de gösterildiği gibi “MX_IWDG_Init();” fonksiyonu üzerine Ctrl tuşuna basarak
tıklıyoruz. Fonksiyonun bulunduğu konum gelecektir.
Aslında HAL kütüphaneleri register seviyesinde bizim
yapmamız gereken işleri kendi halletmiş durumda. Biz sadece bahsi geçen
parametreleri giriyoruz. Kısaca konu başında anlatılan Key register vb.
register’ların içeriği kütüphane içinde halledilmiş oluyor. Merak edenler için
HAL_IWDG_Init fonksiyonunu incelemelerini öneririm. Yukarıdaki resimde de
görüldüğü gibi formüle yerleştirdiğimiz değerler parametrelere set edilmiş
durumdalar.
Öncelikle IWDG counter’ı yenilemeden sistemin reset'lendiğini
görmek için main fonksiyonu içerisini aşağıdaki gibi değiştirelim.
Öncelikle MX_IWDG_Init() fonksiyonundan sonra 2000ms’lik bir
gecikme fonksiyonu ekledik. Daha sonra while döngüsü içerisine Hal_Delay(50)
fonksiyonu ile 50ms’lik bir gecikme ve Kırmızı LED’imizi her seferinde yakıp
söndürecek HAL_GPIO_TogglePin fonksiyonunu ekledik. Programı derleyip
çalıştırdığımızda kırmızı LED’in üzerindeki sinyal aşağıdaki gibi olacaktır.
Osilaskop görüntüsünde de görüldüğü gibi LED periyodik
olarak yanıp sönüyor ve reset sinyalinden sonra tekrar periyodik yanıp sönüyor.
Şimdi IWDG counter’ı yenileyerek aynı kodu çalıştıralım.
Yukarıdaki kod parçasında görüldüğü gibi while döngüsünün
içerisine IWDG counter’ı yenileyen fonksiyon olan HAL_IWDG_Refresh eklendi. Yani
yaklaşık 50ms’de bir watchdog sayacı yenilenecek ve böylece reset sinyali
oluşmayacak. Kodu çalıştırdığımızda ki osilaskop görüntüsü aşağıdaki gibidir.
Kırmızı LED periyodik hiç ara vermeksizin 50ms’de bir yanıp
sönüyor. Bu durumda iken işlemcinin ana clock sinyali fail eder ise reset
sinyali üretilecek ve program tekrar çalışmaya başlayacaktır.
İyi çalışmalar arkadaşlar.....