Merhaba,
Uzun bir aradan sonra yeni bir makale ile sizlerle paylaşımlara devam ediyorum 🙂
Bu makalemizde STM32F070 Nucleo Board üzerinde Watchdog Timer kullanımını (IWDG) öğrenecek ve uygulayacağız. Uygulamamızda CubeMX programından ve HAL kütüphanelerinden yararlanacağız.
Uygulamayı STM32F070 üzerinden anlatsam da , tüm ST serileri için aynı işlem adımları ve mantık geçerlidir.
Uygulamamıza başlamadan önce basitçe Watchdog Timer‘dan bahsedelim.
Watchdog timer birçok mikrodenetleyicide yer alan bir birimdir.
Belirli bir periyot için bu timer kurulur. Bu periyot içinde timer’ı refresh etmezsek, işlemcimizin otomatik reset atmasını sağlar.
Eğer yazılımda bir döngünün gereğinden uzun sürmesi, yada o döngüde yazılımınızın takılması durumunda, sistemin kendi kendine reset atmasını istiyorsak; Watchdog timer özelliğinden yararlanabiliriz.
Eğer kodumuzun içerisinde Watchdog timer’ı periyodu dolmadan refresh edersek, periyodu dolana kadar işlemcimize reset attırmaz. Takılacağından veya gereğinden uzun süreceğinden şüphe duyduğumuz döngü veya fonksiyonumuzdan sonra Watchdog timer’ı periyodundan önce refresh ederek; hem bu işlemin istenen sürede tamamlandığını garanti etmiş; hem de istenen sürede tamamlandığında reset atılmasını önlemiş oluruz.
Eğer fonksiyonumuz veya döngümüz Watchdog Timer’ın periyodundan önce tamamlanamazsa, işlem bitiminde Watchdog timer’ı refresh edemeyiz ve işlemciye otomatik reset attırılır.
Bu sayede yazılımda takılma durumlarının önüne geçebilir, kritik zamanlama durumları için önlem alabiliriz.
Şimdi bunu uygulayarak daha iyi anlayabilirsiniz. Uygulama adımlarına geçiyorum 🙂
Tüm resimler üstüne tıklandığında büyür 🙂
1) CubeMX programını açarak, kullanacağınız mikrodenetleyiciyi tanımlayın. Sonrasında IWDG’yi aktif edin ve bir adet pini GPIO_Output olarak ayarlayın. Bu pine bir LED bağlamanız, sistemin çalışmasını gözlemlememizi sağlayacak. Nucleo-070RB Board’unda PA5’e 1 adet User LED bağlıdır.
2) Clock Configuration sekmesine gelerek MCU’muzun clock ayarlarını yapalım. Resimde Nucleo – 070RB Board’u için yaptığım ayarları gösteriyorum.
Resimde dikkat ediniz, IWDG bloğumuzun LSI clock’u üzerinden beslendiğini göreceksiniz. (Yeşil kutu) Bunu bilmek bir sonraki adımda Watchdog timer’ımızın periyot ayarlarını yaparken bize gerekli olacak 🙂
3) Configuration sekmesine gelerek IWDG‘ye tıklayın. Karşımıza gelen pencereden Watchdog timerımızın periyodu ile ilgili ayarlar yapacağız.
STM32F070’in Datasheet dosyasını incelediğimizde, Watchdog timer’ın periyot ayarları ile ilgili şunu görmekteyiz.
Bu tabloyu şöyle yorumluyoruz:
Prescaler 4 seçer , window ve reload kısmına 0xFFF yani 4095 yazarsak ; periyodumuz 409.6 ms, 0x000 yani 0 yazarsak periyodumuz 0.1 ms olur.
Bundan yola çıkarak Prescaler 16 , windows ve reload 4095 olduğunda ; watchdog timer’ın periyodu 1638.4 ms olacaktır.
Buradaki prescaler değerini değiştirerek; window ve reload değerlerini verilen sürelere orantı kurarak ayarlarsanız, istediğiniz watchdog timer periyodunu elde edebilirsiniz. Bunu yazılımınızın kritikliğine göre kendiniz ayarlayabilirsiniz. 🙂
4) Ayarları yaptıktan sonra CubeMX üzerinden projemizi, kullandığımız derleyici ile oluşturalım. Açılan projemizde MX_IWDG_Init() fonksiyonunun çağrıldığını göreceksiniz. Resimde gösterdiğim noktaya Breakpoint koyunuz.
Kodun geri kalan kısmını aşağıdaki örnek gibi tamamlayınız.
Eğer işin içinde Watchdog timer olmasaydı, bu kodun basitçe LED’i 0.5 sn aralıkla yakıp-söndürmesini bekleyebilirdik. Fakat şuanki haliyle, Watchdog timer’ı refresh etmediğimiz için, LED yanıp sönerken, watchdog timer’ın periyodu dolacak ve MCU reset atacaktır. Dolayısı ile kodu debug ettiğinizde , reset atarak HAL_Init() fonksiyonunun tekrar çağrıldığını görebilirsiniz. Ayrıca LED’e bakarsanız, LED’in olması gerektiği gibi çalışmadığını görebilirsiniz.
5) Şimdi Watchdog Timer’ı refresh edelim.
Şimdi normal LED yakıp-söndürme işlemimiz yaparken, her döngüde Watchdog timer’ı refresh etmiş oluyoruz. Bizim işlem süremiz watchdog timer’ın periyodundan kısa sürdüğü için, watchdog timer periyodu dolmadan onu refresh edebiliyoruz. Kodu debug ettiğinizde HAL_Init()’deki breakpoint’e tekrar bir yönlenme olmadığını; yani MCU’nun reset yemediğini görebilirsiniz. LED ise beklenen şekilde çalışacaktır.
Eğer işlemlerimiz Watchdog timer periyodundan uzun sürseydi, Refresh fonksiyonuna gelene kadar; periyot dolacak ve MCU reset yemiş olacaktı.
Umarım anlatım faydalı olmuştur 🙂
Çalışmalarınızda başarılar.
Çağatay KAYNAK
Gömülü Yazılım Mühendisi
cagataykaynak@gmail.com
Bir yanıt yazın